commit db114eb23f64a86fe8034ec4f55f330fbaf0a5f8 Author: Dayve Date: Thu May 5 01:03:15 2016 +1000 Add project files. diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..1ff0c423 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..8369c337 --- /dev/null +++ b/.gitignore @@ -0,0 +1,249 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +*.xml +*.cfg +Data/ + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +[Xx]64/ +[Xx]86/ +[Bb]uild/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml + +# TODO: Un-comment the next line if you do not want to checkin +# your web deploy settings because they may include unencrypted +# passwords +#*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Microsoft Azure ApplicationInsights config file +ApplicationInsights.config + +# Windows Store app package directory +AppPackages/ +BundleArtifacts/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# LightSwitch generated files +GeneratedArtifacts/ +ModelManifest.xml + +# Paket dependency manager +.paket/paket.exe + +# FAKE - F# Make +.fake/ \ No newline at end of file diff --git a/Build.lua b/Build.lua new file mode 100644 index 00000000..ddc3c31f --- /dev/null +++ b/Build.lua @@ -0,0 +1,310 @@ +local launch, cfg, main = ... + +local ipairs = ipairs +local t_insert = table.insert + +local buildMode = { } + +buildMode.controls = { } + +t_insert(buildMode.controls, common.newButton(4, 4, 60, 20, "<< Back", function() + main:SetMode("LIST", buildMode.dbFileName) +end)) + +t_insert(buildMode.controls, common.newButton(4 + 68, 4, 60, 20, "Tree", function() + buildMode.viewMode = "TREE" +end, function() + return buildMode.viewMode ~= "TREE" +end)) + +t_insert(buildMode.controls, common.newButton(4 + 68*2, 4, 60, 20, "Items", function() + buildMode.viewMode = "ITEMS" +end, function() + return buildMode.viewMode ~= "ITEMS" +end)) + +t_insert(buildMode.controls, common.newButton(4 + 68*3, 4, 60, 20, "Calcs", function() + buildMode.viewMode = "CALCS" +end, function() + return buildMode.viewMode ~= "CALCS" +end)) + +t_insert(buildMode.controls, { + x = 4 + 68*4, + y = 4, + Draw = function(self) + local buildName = buildMode.dbFileName:gsub(".xml","") + local bnw = DrawStringWidth(16, "VAR", buildName) + SetDrawColor(0.5, 0.5, 0.5) + DrawImage(nil, self.x + 91, self.y, bnw + 6, 20) + SetDrawColor(0, 0, 0) + DrawImage(nil, self.x + 92, self.y + 1, bnw + 4, 18) + SetDrawColor(1, 1, 1) + DrawString(self.x, self.y + 2, "LEFT", 16, "VAR", "Current build: "..buildName.." "..((buildMode.calcs.modFlag or buildMode.spec.modFlag or buildMode.items.modFlag) and "(Unsaved)" or "")) + end, +}) + +buildMode.controls.pointDisplay = { + x = 0, + y = 4, + Draw = function(self) + local used, ascUsed = buildMode.spec:CountAllocNodes() + local usedMax = 120 + (buildMode.calcs.output.total_extraPoints or 0) + local ascMax = 6 + local str = string.format("%s%3d / %3d %s%d / %d", used > usedMax and "^1" or "^7", used, usedMax, ascUsed > ascMax and "^1" or "^7", ascUsed, ascMax) + local strW = DrawStringWidth(16, "FIXED", str) + 6 + SetDrawColor(1, 1, 1) + DrawImage(nil, self.x, self.y, strW + 2, 20) + SetDrawColor(0, 0, 0) + DrawImage(nil, self.x + 1, self.y + 1, strW, 18) + SetDrawColor(1, 1, 1) + DrawString(self.x + 4, self.y + 2, "LEFT", 16, "FIXED", str) + end, +} + +buildMode.controls.classDrop = common.newDropDown(0, 4, 100, 20, nil, function(index, val) + local classId = main.tree.classNameMap[val] + if classId ~= buildMode.spec.curClassId then + if buildMode.spec:IsClassConnected(classId) or buildMode.spec:CountAllocNodes() == 0 then + buildMode.spec:SelectClass(classId) + buildMode.spec:AddUndoState() + else + launch:ShowPrompt(0, 0, 0, "Changing class to "..val.." will reset your tree.\nThis can be avoided by connecting one of the "..val.." starting nodes to your tree.\n\nPress Y to continue.", function(key) + if key == "y" then + buildMode.spec:SelectClass(classId) + buildMode.spec:AddUndoState() + end + return true + end) + end + end +end, function() + return buildMode.viewMode == "TREE" +end) + +buildMode.controls.ascendDrop = common.newDropDown(0, 4, 100, 20, nil, function(index, val) + local ascendClassId = main.tree.ascendNameMap[val].ascendClassId + buildMode.spec:SelectAscendClass(ascendClassId) + buildMode.spec:AddUndoState() +end, function() + return buildMode.viewMode == "TREE" +end) + +buildMode.savers = { + ["Build"] = "", + ["Calcs"] = "calcs", + ["Items"] = "items", + ["Spec"] = "spec", + ["TreeView"] = "treeView", +} + +function buildMode:LoadDB() + local dbXML, errMsg = common.xml.LoadXMLFile(self.dbFileName) + if not dbXML then + launch:ShowErrMsg("^1Error loading '%s': %s", self.dbFileName, errMsg) + return true + elseif dbXML[1].elem ~= "PathOfBuilding" then + launch:ShowErrMsg("^1Error parsing '%s': 'PathOfBuilding' root element missing", self.dbFileName) + return true + end + for _, node in ipairs(dbXML[1]) do + if type(node) == "table" then + local key = self.savers[node.elem] + if key then + local saver = self[key] or self + if saver:Load(node, self.dbFileName) then + return true + end + end + end + end +end +function buildMode:SaveDB() + local dbXML = { elem = "PathOfBuilding" } + for elem, key in pairs(self.savers) do + local saver = self[key] or self + local node = { elem = elem } + saver:Save(node) + t_insert(dbXML, node) + end + local res, errMsg = common.xml.SaveXMLFile(dbXML, self.dbFileName) + if not res then + launch:ShowErrMsg("Error saving '%s': %s", self.dbFileName, errMsg) + return true + end +end + +function buildMode:Load(xml, fileName) + if xml.attrib.viewMode then + self.viewMode = xml.attrib.viewMode + end +end +function buildMode:Save(xml) + xml.attrib = { + viewMode = self.viewMode, + className = self.tree.classes[self.spec.curClassId].name, + ascendClassName = self.spec.curAscendClassId > 0 and self.tree.classes[self.spec.curClassId].classes[tostring(self.spec.curAscendClassId)].name, + level = tostring(self.calcs.input.player_level or 1) + } +end + +function buildMode:Init(dbFileName) + self.dbFileName = dbFileName + ConPrintf("Loading '%s'...", dbFileName) + + self.abortSave = true + + self.items = LoadModule("Items", launch, cfg, main) + self.items:Init(self) + self.calcs = LoadModule("Calcs", launch, cfg, main) + self.calcs:Init(self) + self.tree = main.tree + self.spec = main.SpecClass.NewSpec(main.tree) + self.treeView = main.TreeViewClass.NewTreeView() + + wipeTable(self.controls.classDrop.list) + for classId, class in pairs(self.tree.classes) do + t_insert(self.controls.classDrop.list, class.name) + end + table.sort(self.controls.classDrop.list) + + self.displayStats = { + { mod = "total_avg", label = "Average Hit", fmt = ".1f" }, + { mod = "total_speed", label = "Speed", fmt = ".2f" }, + { mod = "total_critChance", label = "Crit Chance", fmt = ".2f%%", pc = true }, + { mod = "total_critMultiplier", label = "Crit Multiplier", fmt = "d%%", pc = true }, + { mod = "total_hitChance", label = "Hit Chance", fmt = "d%%", pc = true }, + { mod = "total_dps", label = "Total DPS", fmt = ".1f" }, + { mod = "ignite_dps", label = "Ignite DPS", fmt = ".1f" }, + { mod = "poison_dps", label = "Poison DPS", fmt = ".1f" }, + { }, + { mod = "spec_lifeInc", label = "Life %", fmt = "d" }, + { mod = "total_life", label = "Total Life", fmt = "d" }, + { }, + { mod = "total_mana", label = "Total Mana", fmt = "d" }, + { mod = "total_manaRegen", label = "Mana Regen", fmt = ".1f" }, + { }, + { mod = "total_energyShield", label = "Energy Shield", fmt = "d" }, + { mod = "total_evasion", label = "Evasion rating", fmt = "d" }, + { mod = "total_armour", label = "Armour", fmt = "d" }, + { mod = "total_blockChance", label = "Block Chance", fmt = "d%%" }, + { }, + { mod = "total_fireResist", label = "Fire Resistance", fmt = "d%%" }, + { mod = "total_coldResist", label = "Cold Resistance", fmt = "d%%" }, + { mod = "total_lightningResist", label = "Lightning Resistance", fmt = "d%%" }, + { mod = "total_chaosResist", label = "Chaos Resistance", fmt = "d%%" }, + } + + self.viewMode = "TREE" + + if self:LoadDB() then + main:SetMode("LIST", dbFileName) + return + end + + --[[local start = GetTime() + SetProfiling(true) + for i = 1, 10 do + self.calcs:BuildPower(self) + end + SetProfiling(false) + ConPrintf("Power build time: %d msec", GetTime() - start)]] + + self.abortSave = false +end + +function buildMode:Shutdown() + if not self.abortSave then + self:SaveDB() + end + self.abortSave = nil + + self.calcs:Shutdown() + self.calcs = nil + self.items:Shutdown() + self.items = nil + self.spec = nil + self.treeView = nil +end + +function buildMode:OnFrame(inputEvents) + common.controlsInput(self, inputEvents) + for id, event in ipairs(inputEvents) do + if event.type == "KeyDown" then + if event.key == "s" and IsKeyDown("CTRL") then + self:SaveDB() + inputEvents[id] = nil + end + end + end + + local class = main.tree.classes[self.spec.curClassId] + local ascendClass = class.classes[tostring(self.spec.curAscendClassId)] + wipeTable(self.controls.ascendDrop.list) + for _, ascendClass in pairs(main.tree.classes[self.spec.curClassId].classes) do + t_insert(self.controls.ascendDrop.list, ascendClass.name) + end + table.sort(self.controls.ascendDrop.list) + + self.controls.classDrop:SelByValue(class.name) + self.controls.ascendDrop:SelByValue(ascendClass and ascendClass.name or "None") + + self.controls.pointDisplay.x = cfg.screenW / 2 + 6 + self.controls.classDrop.x = self.controls.pointDisplay.x + 154 + self.controls.ascendDrop.x = self.controls.classDrop.x + self.controls.classDrop.width + 8 + + self.calcs:RunControl(self) + + if self.viewMode == "TREE" then + local viewPort = { + x = 258, + y = 32, + width = cfg.screenW - 258, + height = cfg.screenH - 32 + } + self.treeView:DrawTree(self, viewPort, inputEvents) + elseif self.viewMode == "CALCS" then + local viewPort = { + x = 0, + y = 32, + width = cfg.screenW, + height = cfg.screenH - 32 + } + self.calcs:DrawGrid(viewPort, inputEvents) + elseif self.viewMode == "ITEMS" then + local viewPort = { + x = 258, + y = 32, + width = cfg.screenW - 258, + height = cfg.screenH - 32 + } + self.items:DrawItems(viewPort, inputEvents) + end + + SetDrawColor(0.2, 0.2, 0.2) + DrawImage(nil, 0, 0, cfg.screenW, 28) + SetDrawColor(0.85, 0.85, 0.85) + DrawImage(nil, 0, 28, cfg.screenW, 4) + DrawImage(nil, cfg.screenW/2 - 2, 0, 4, 28) + common.controlsDraw(self, viewPort) + if self.viewMode ~= "CALCS" then + SetDrawColor(0.1, 0.1, 0.1) + DrawImage(nil, 0, 32, 254, cfg.screenH - 32) + SetDrawColor(0.85, 0.85, 0.85) + DrawImage(nil, 254, 32, 4, cfg.screenH - 32) + local y = 36 + for index, data in ipairs(self.displayStats) do + if data.mod then + if self.calcs.output[data.mod] and self.calcs.output[data.mod] ~= 0 then + DrawString(150, y, "RIGHT_X", 16, "VAR", data.label..":") + DrawString(154, y, "LEFT", 16, "VAR", string.format("%"..data.fmt, self.calcs.output[data.mod] * (data.pc and 100 or 1))) + y = y + 16 + end + else + y = y + 12 + end + end + end +end + +return buildMode \ No newline at end of file diff --git a/Calcs.lua b/Calcs.lua new file mode 100644 index 00000000..20d9b5bd --- /dev/null +++ b/Calcs.lua @@ -0,0 +1,665 @@ +local launch, cfg, main = ... + +cfg.gridHeight = 18 +cfg.defGridWidth = 50 +cfg.defBorderCol = { 0.1, 0.1, 0.1 } +cfg.defCellCol = { 0, 0, 0 } + +local pairs = pairs +local t_insert = table.insert +local m_max = math.max +local m_floor = math.floor + +local function alignCellText(e) + if e.align == "RIGHT" then + return cfg.screenW - (e.grid.offX + e.x + e.grid[e.gx].width - 2) + elseif e.align == "CENTER" then + return - cfg.screenW / 2 + e.grid.offX + e.x + e.grid[e.gx].width / 2 + else + return e.grid.offX + e.x + 2 + end +end + +local function formatCellText(fn, val) + if fn then + local errMsg, text = PCall(fn, val) + if errMsg then + launch:ShowErrMsg("Error formatting cell: %s", errMsg) + return "" + else + return text + end + else + return tostring(val) + end +end + +local elem = {} + +elem.input = {} +elem.input.__index = elem.input +elem.input.borderCol = { 0.9, 0.9, 0.9 } +elem.input.cellCol = { 0.1, 0.1, 0.4 } +function elem.input:Init() + local grid = self.grid + if self.format == "choice" then + self.dropDown = common.newDropDown(0, 0, 0, 0, self.list, function(index, val) + if val ~= grid.input[self.name] then + grid.input[self.name] = val + grid.changeFlag = true + end + end) + self.dropDown.sel = 1 + end +end +function elem.input:Draw() + local grid = self.grid + if self.format == "check" then + DrawString(alignCellText(self), grid.offY + self.y + 2, self.align, cfg.gridHeight - 4, "FIXED", grid.input[self.name] and "^x33FF33Yes" or "^xFF3333No") + elseif grid.focus == self then + if self.edit then + self.edit:Draw() + else + self.dropDown:Draw() + end + elseif grid.input[self.name] then + DrawString(alignCellText(self), grid.offY + self.y + 2, self.align, cfg.gridHeight - 4, "VAR", "^7"..formatCellText(self.formatFunc, grid.input[self.name])) + end +end +function elem.input:OnKeyDown(key, doubleClick) + local grid = self.grid + if grid.focus == self then + if key == "RETURN" or key == "TAB" then + if self.edit then + local newVal = #self.edit.buf and self.edit.buf or nil + if self.format == "number" then + newVal = tonumber((newVal:gsub(",",""):gsub("%*","e"))) + end + if newVal ~= grid.input[self.name] then + grid.input[self.name] = newVal + grid.changeFlag = true + end + end + grid:SetFocus() + grid:MoveSel(key == "TAB" and "RIGHT" or "DOWN", true) + elseif self.edit then + self.edit:OnKeyDown(key) + elseif self.dropDown then + if self.dropDown:OnKeyDown(key) then + grid:SetFocus() + end + end + elseif key == "RIGHTBUTTON" or (key == "LEFTBUTTON" and doubleClick) then + if self.format == "check" then + grid.input[self.name] = not grid.input[self.name] + grid.changeFlag = true + elseif self.format == "choice" then + grid:SetFocus(self) + else + grid:SetFocus(self) + self.edit:SetText(grid.input[self.name] or "") + end + elseif key == "WHEELUP" then + if self.format == "number" then + grid.input[self.name] = (grid.input[self.name] or 0) + 1 + grid.changeFlag = true + end + elseif key == "WHEELDOWN" then + if self.format == "number" then + grid.input[self.name] = (grid.input[self.name] or 0) - 1 + grid.changeFlag = true + end + elseif self.edit then + if key == "c" and IsKeyDown("CTRL") then + if grid.input[self.name] then + Copy(tostring(grid.input[self.name])) + end + elseif key == "v" and IsKeyDown("CTRL") then + local newVal = Paste() + if newVal then + if self.format == "number" then + newVal = tonumber(newVal) + end + if newVal ~= grid.input[self.name] then + grid.input[self.name] = newVal + grid.changeFlag = true + end + end + end + end +end +function elem.input:OnKeyUp(key) + local grid = self.grid + if grid.focus == self then + if self.dropDown then + if self.dropDown:OnKeyUp(key) then + grid:SetFocus() + end + else + self.edit:OnKeyUp(key) + end + end +end +function elem.input:OnChar(key) + local grid = self.grid + if self.format == "check" then + if key == " " then + grid.input[self.name] = not grid.input[self.name] + grid.changeFlag = true + end + return + elseif self.format == "choice" then + return + end + if key == "\r" then + return + elseif not grid.focus and key == "\b" then + grid.input[self.name] = nil + grid.changeFlag = true + return + elseif key:match("%c") then + return + end + if not grid.focus then + if self.format == "number" and key == "+" then + grid.input[self.name] = (grid.input[self.name] or 0) + 1 + grid.changeFlag = true + return + end + grid:SetFocus(self) + end + self.edit:OnChar(key) +end +function elem.input:OnFocusGained() + local grid = self.grid + if self.format == "choice" then + self.dropDown.x = grid.offX + self.x + self.dropDown.y = grid.offY + self.y + self.dropDown.width = grid:GetElemWidth(self) + self.dropDown.height = cfg.gridHeight + self.dropDown:SelByValue(grid.input[self.name]) + self.dropDown:OnKeyDown("LEFTBUTTON") + else + local fmtFilter = { number = "[-%d%.e,*]", string = "." } + self.edit = common.newEditField(nil, nil, fmtFilter[self.format]) + self.edit.x = grid.offX + self.x + 2 + self.edit.y = grid.offY + self.y + 2 + self.edit.width = grid:GetElemWidth(self) + self.edit.height = cfg.gridHeight - 4 + end +end +function elem.input:OnFocusLost() + self.edit = nil + if self.dropDown then + self.dropDown.dropped = false + end +end + +elem.output = {} +elem.output.__index = elem.output +elem.output.borderCol = { 0.7, 0.7, 0.7 } +function elem.output:Draw() + local grid = self.grid + if grid.output[self.name] then + DrawString(alignCellText(self), grid.offY + self.y + 2, self.align, cfg.gridHeight - 4, self.font or "VAR", "^7"..formatCellText(self.formatFunc, grid.output[self.name])) + end +end +function elem.output:OnKeyDown(key) + local grid = self.grid + if key == "c" and IsKeyDown("CTRL") and grid.output[self.name] then + Copy(tostring(grid.output[self.name])) + end +end + +elem.label = {} +elem.label.__index = elem.label +function elem.label:Draw() + local grid = self.grid + DrawString(alignCellText(self), grid.offY + self.y + 2, self.align, cfg.gridHeight - 4, "VAR BOLD", "^xD0D5D0"..self.text) +end + +local grid = { } +function grid:Clear() + for gx in ipairs(self) do + self[gx] = nil + end + self.width = 1 + self.height = 1 + self[1] = { width = cfg.defGridWidth, x = 0 } + self:CalcCoords() +end +function grid:SetSize(w, h) + if w < self.width then + for gx = w + 1, self.width do + self[gx] = nil + end + end + self.width = w + self.height = h + for gx = 1, w do + self[gx] = self[gx] or { width = cfg.defGridWidth } + end + self:CalcCoords() +end +function grid:CalcCoords() + local x = 0 + for gx = 1, self.width do + self[gx].x = x + for gy = 1, self.height do + if self[gx][gy] and self[gx][gy].gx == gx then + self[gx][gy].x = x + end + end + x = x + self[gx].width + end + self.realWidth = x + self.realHeight = self.height * cfg.gridHeight +end +function grid:CheckSize() + local mx, my = 1, 1 + for gx = 1, self.width do + for gy = 1, self.height do + if self[gx][gy] then + mx = math.max(mx, gx + self[gx][gy].width - 1) + my = math.max(my, gy) + end + end + end + grid:SetSize(mx, my) +end +function grid:SetColWidth(gx, sz) + if self[gx] then + self[gx].width = sz + end + self:CalcCoords() +end +function grid:GetElem(gx, gy) + return self[gx] and self[gx][gy] +end +function grid:SetElem(gx, gy, e) + if e then + e.grid = self + e.gx = gx + e.gy = gy + e.width = e.width or 1 + if gx + e.width - 1 > self.width then + grid:SetSize(gx + e.width - 1, self.height) + end + if gy > self.height then + grid:SetSize(self.width, gy) + end + for i = 1, e.width do + grid[gx + i - 1][gy] = e + end + e.x = grid[gx].x + e.y = (gy - 1) * cfg.gridHeight + if elem[e.type] then + setmetatable(e, elem[e.type]) + end + if e.Init then + e:Init() + end + elseif self:GetElem(gx, gy) then + self[gx][gy] = nil + self:CheckSize() + end +end +function grid:GetElemWidth(e) + local width = 0 + for gx = e.gx, e.gx + e.width - 1 do + width = width + self[gx].width + end + return width +end +function grid:SetFocus(e) + if self.focus and self.focus.OnFocusLost then + self.focus:OnFocusLost() + end + self.focus = e + if self.focus and self.focus.OnFocusGained then + self.focus:OnFocusGained() + end +end +function grid:MoveSel(dir, force) + if not self.sel or not self.sel.gx then + return + end + local selX, selY = self.sel.gx, self.sel.gy + local s, e, i + if dir == "LEFT" or dir == "RIGHT" then + if dir == "LEFT" then + s, e, i = selX - 1, 1, -1 + else + s, e, i = selX + 1, self.width, 1 + end + for gx = s, e, i do + if self[gx][selY] then + self.sel = self[gx][selY] + return + end + end + else + if dir == "UP" then + s, e, i = selY - 1, 1, -1 + else + s, e, i = selY + 1, self.height, 1 + end + for gy = s, e, i do + if self[selX][gy] then + self.sel = self[selX][gy] + return + end + end + end + if force then + self.sel = nil + end +end +function grid:Draw() + local x = self.offX + local h = cfg.gridHeight + for gx = 1, self.width do + local y = self.offY + local w = self[gx].width + for gy = 1, self.height do + local e = self[gx][gy] + if not e or e.gx == gx then + local ew = w + if e and e.width and e.width > 1 then + for i = 1, e.width - 1 do + ew = ew + self[gx + i].width + end + end + SetDrawColor(unpack(e and e.borderCol or cfg.defBorderCol)) + DrawImage(nil, x, y, ew, h) + SetDrawColor(unpack(e and e.cellCol or cfg.defCellCol)) + DrawImage(nil, x + 1, y + 1, ew - 2, h - 2) + end + y = y + cfg.gridHeight + end + x = x + self[gx].width + end + for gx = 1, self.width do + for gy = 1, self.height do + local e = self[gx][gy] + if e and e.gx == gx and e.Draw and e ~= self.focus then + e:Draw() + end + end + end + if self.focus then + self.focus:Draw() + end + if self.sel and self.sel.gx then + local selX, selY = self.sel.gx, self.sel.gy + SetDrawColor(1, 1, 1) + local x, y = self.sel.x + self.offX, self.sel.y + self.offY + local w, h = self:GetElemWidth(self.sel), cfg.gridHeight + DrawImage(nil, x - 2, y - 2, w + 4, 4) + DrawImage(nil, x - 2, y + h - 2, w + 4, 4) + DrawImage(nil, x - 2, y - 2, 4, h + 4) + DrawImage(nil, x + w - 2, y - 2, 4, h + 4) + end +end +function grid:OnKeyDown(key, doubleClick) + if self.focus then + if self.focus.OnKeyDown then + self.focus:OnKeyDown(key, doubleClick) + end + elseif key == "LEFTBUTTON" or key == "RIGHTBUTTON" then + self.sel = nil + local cx, cy = GetCursorPos() + local gcx, gcy = cx - self.offX, cy - self.offY + local gy = math.floor(gcy / cfg.gridHeight) + 1 + if gcx >= 0 and gcy >= 0 and gcx < self.realWidth and gcy < self.realHeight then + local x = 0 + for gx = 1, self.width do + if gcx >= x and gcx < x + self[gx].width then + if self[gx][gy] then + local e = self[gx][gy] + self.sel = e + if e.OnKeyDown then + e:OnKeyDown(key, doubleClick) + end + end + return + end + x = x + self[gx].width + end + end + elseif key == "LEFT" or key == "RIGHT" or key == "UP" or key == "DOWN" then + self:MoveSel(key) + elseif self.sel then + if self.sel.OnKeyDown then + self.sel:OnKeyDown(key) + end + end +end +function grid:OnKeyUp(key) + if self.focus then + if key == "ESCAPE" then + self:SetFocus() + elseif self.focus.OnKeyUp then + self.focus:OnKeyUp(key) + end + elseif key == "ESCAPE" then + self.sel = nil + elseif self.sel then + if self.sel.OnKeyUp then + self.sel:OnKeyUp(key) + end + end +end +function grid:OnChar(key) + if self.focus then + if self.focus.OnChar then + self.focus:OnChar(key) + end + elseif self.sel then + if self.sel.OnChar then + self.sel:OnChar(key) + end + end +end + +local calcs = { } + +function calcs:Init(build) + self.build = build + self.input = { } + self.output = { } + grid.input = self.input + grid.output = self.output + grid:Clear() + self.undo = { } + self.redo = { } + self:LoadControl() +end +function calcs:Shutdown() + grid:SetFocus() + grid:Clear() + self.redo = nil + self.undo = nil +end + +function calcs:Load(xml, dbFileName) + for _, node in ipairs(xml) do + if type(node) == "table" then + if node.elem == "Input" then + if not node.attrib.name then + launch:ShowErrMsg("^1Error parsing '%s': 'Input' element missing name attribute", fileName) + return true + end + if node.attrib.number then + self.input[node.attrib.name] = tonumber(node.attrib.number) + elseif node.attrib.string then + self.input[node.attrib.name] = node.attrib.string + elseif node.attrib.boolean then + self.input[node.attrib.name] = node.attrib.boolean == "true" + else + launch:ShowErrMsg("^1Error parsing '%s': 'Input' element missing number, string or boolean attribute", fileName) + return true + end + end + end + end + self:AddUndoState() + self.buildFlag = true +end +function calcs:Save(xml) + self.modFlag = false + for k, v in pairs(self.input) do + local child = {elem = "Input", attrib = {name = k}} + if type(v) == "number" then + child.attrib.number = tostring(v) + elseif type(v) == "boolean" then + child.attrib.boolean = tostring(v) + else + child.attrib.string = tostring(v) + end + t_insert(xml, child) + end +end + +function calcs:AddUndoState() + t_insert(self.undo, 1, copyTable(self.input)) + self.undo[102] = nil +end + +function calcs:LoadControl() + grid:Clear() + local errMsg + errMsg, self.control = PLoadModule("CalcsControl", grid) + if errMsg then + launch:ShowErrMsg("Error loading control script: %s", errMsg) + elseif not self.control then + launch:ShowErrMsg("Error loading control script: no object returned") + end +end + +function calcs:RunControl() + if grid.changeFlag then + grid.changeFlag = false + self.modFlag = true + self.buildFlag = true + self:AddUndoState() + if not self.noClearRedo then + self.redo = {} + end + self.noClearRedo = false + end + if self.buildFlag or self.build.spec.buildFlag or self.build.items.buildFlag then + self.buildFlag = false + self.build.spec.buildFlag = false + self.build.items.buildFlag = false + wipeTable(self.output) + if self.control and self.control.buildOutput then + local errMsg, otherMsg = PCall(self.control.buildOutput, grid.input, grid.output, self.build) + if errMsg then + launch:ShowErrMsg("Error building output: %s", errMsg) + elseif otherMsg then + launch:ShowPrompt(1, 0.5, 0, otherMsg.."\n\nEnter/Escape to Dismiss", function(key) + if key == "RETURN" or key == "ESCAPE" then + return true + end + end) + end + end + self.powerBuildFlag = true + end +end + +function calcs:BuildPower() + local calcFunc, base = self:GetNodeCalculator() + if not calcFunc then + return + end + local cache = { } + self.powerMax = { } + for _, node in pairs(self.build.spec.nodes) do + node.power = wipeTable(node.power) + if not node.alloc and node.modKey ~= "" then + if not cache[node.modKey] then + cache[node.modKey] = calcFunc({node}) + end + local output = cache[node.modKey] + local dpsKey = base.mode_average and "total_avg" or "total_dps" + node.power.dps = (output[dpsKey] - base[dpsKey]) / base[dpsKey] + node.power.def = (output.total_life - base.total_life) / m_max(2000, base.total_life) * 0.5 + + (output.total_armour - base.total_armour) / m_max(10000, base.total_armour) + + (output.total_energyShield - base.total_energyShield) / m_max(2000, base.total_energyShield) + + (output.total_evasion - base.total_evasion) / m_max(10000, base.total_evasion) + + (output.total_lifeRegen - base.total_lifeRegen) / 500 + if node.path then + self.powerMax.dps = m_max(self.powerMax.dps or 0, node.power.dps) + self.powerMax.def = m_max(self.powerMax.def or 0, node.power.def) + end + end + end + self.powerBuildFlag = false +end + +function calcs:GetNodeCalculator() + if self.control and self.control.getNodeCalculator then + local errMsg, calcFunc, calcBase = PCall(self.control.getNodeCalculator, grid.input, self.build) + if errMsg then + launch:ShowErrMsg("Error creating calculator: %s", errMsg) + elseif otherMsg then + launch:ShowPrompt(1, 0.5, 0, otherMsg.."\n\nEnter/Escape to Dismiss") + end + return calcFunc, calcBase + end +end + +function calcs:GetItemCalculator() + if self.control and self.control.getItemCalculator then + local errMsg, calcFunc, calcBase = PCall(self.control.getItemCalculator, grid.input, self.build) + if errMsg then + launch:ShowErrMsg("Error creating calculator: %s", errMsg) + elseif otherMsg then + launch:ShowPrompt(1, 0.5, 0, otherMsg.."\n\nEnter/Escape to Dismiss") + end + return calcFunc, calcBase + end +end + +function calcs:DrawGrid(viewPort, inputEvents) + grid.offX = viewPort.x + m_floor((viewPort.width - grid.realWidth) / 2) + grid.offY = viewPort.y + 2 + for id, event in ipairs(inputEvents) do + if event.type == "KeyDown" then + if event.key == "r" and IsKeyDown("CTRL") then + self:LoadControl() + self.buildFlag = true + elseif event.key == "z" and IsKeyDown("CTRL") then + if self.undo[2] then + t_insert(self.redo, 1, table.remove(self.undo, 1)) + wipeTable(self.input) + for k, v in pairs(table.remove(self.undo, 1)) do + self.input[k] = v + end + grid.changeFlag = true + self.noClearRedo = true + end + elseif event.key == "y" and IsKeyDown("CTRL") then + if self.redo[1] then + wipeTable(self.input) + for k, v in pairs(table.remove(self.redo, 1)) do + self.input[k] = v + end + grid.changeFlag = true + self.noClearRedo = true + end + else + grid:OnKeyDown(event.key, event.doubleClick) + end + elseif event.type == "KeyUp" then + grid:OnKeyUp(event.key) + elseif event.type == "Char" then + grid:OnChar(event.key) + end + end + grid:Draw() +end + +return calcs \ No newline at end of file diff --git a/CalcsControl.lua b/CalcsControl.lua new file mode 100644 index 00000000..48b01136 --- /dev/null +++ b/CalcsControl.lua @@ -0,0 +1,1399 @@ +local grid = ... + +local m_abs = math.abs +local m_ceil = math.ceil +local m_floor = math.floor +local m_min = math.min +local m_max = math.max +local pairs = pairs +local ipairs = ipairs +local t_insert = table.insert + +local mod_listMerge = mod.listMerge +local mod_dbMerge = mod.dbMerge +local mod_dbUnmerge = mod.dbUnmerge +local mod_dbMergeList = mod.dbMergeList +local mod_dbUnmergeList = mod.dbUnmergeList + +local setViewMode = LoadModule("CalcsView", grid) + +local isElemental = { fire = true, cold = true, lightning = true } + +local dmgTypeList = {"physical", "lightning", "cold", "fire", "chaos"} + +-- Parse gem list specification +local function parseGemSpec(spec, out) + for nameSpec, numSpec in spec:gmatch("(%a[%a ]*)%s+([%d/\\]+)") do + -- Search for gem name using increasingly broad search patterns + local patternList = { + "^"..nameSpec.."$", -- Exact match + "^"..nameSpec:gsub("%l", "%l*%0"), -- Abbreviated words ("CldFr" -> "Cold to Fire") + "^"..nameSpec:gsub("%a", ".*%0") -- Global abbreviation ("CtoF" -> "Cold to Fire") + } + local gemName, gemData + for _, pattern in ipairs(patternList) do + for name, data in pairs(data.gems) do + if name:match(pattern) then + if gemName then + return "Ambiguous gem name '"..nameSpec.."'\nMatches '"..gemName.."', '"..name.."'" + end + gemName = name + gemData = data + end + end + if gemName then + break + end + end + if not gemName then + return "Unrecognised gem name '"..nameSpec.."'" + end + if gemData.unsupported then + return "Gem '"..gemName.."' is unsupported" + end + + -- Parse level/quality specification + local level, qual = numSpec:match("(%d+)[/\\](%d+)") + if level then + level = tonumber(level) + qual = tonumber(qual) + else + level = tonumber(numSpec) + qual = 0 + end + if not level or level < 1 or level > #gemData.levels or qual < 0 then + return "Invalid level or level/quality specification '"..numSpec.."'" + end + + -- Add to output list + t_insert(out, { + name = gemName, + level = level, + qual = qual, + data = gemData + }) + end +end + +-- Combine specified modifiers from all current namespaces +function sumMods(modDB, mult, ...) + local activeWatchers = modDB._activeWatchers + local val = mult and 1 or 0 + for i = 1, select('#', ...) do + local modName = select(i, ...) + if modName then + for space, spaceName in pairs(modDB._spaces) do + local modVal = space[modName] + if modVal then + val = mult and (val * modVal) or (val + modVal) + end + if activeWatchers then + local fullName = (spaceName and spaceName.."_" or "") .. modName + for watchList in pairs(activeWatchers) do + watchList[fullName] = mult and 1 or 0 + end + end + end + end + end + return val +end + +-- Get value of misc modifier +function getMiscVal(modDB, spaceName, modName, default) + local space = modDB[spaceName or "global"] + local val = default + if space and space[modName] ~= nil then + val = space[modName] + end + if modDB._activeWatchers then + local fullName = (spaceName and spaceName.."_" or "") .. modName + for watchList in pairs(modDB._activeWatchers) do + watchList[fullName] = default + end + if not space then + modDB[spaceName] = { } + end + end + return val +end + +-- Calculate value, optionally adding additional base or increased +function calcVal(modDB, name, base, inc) + local baseVal = sumMods(modDB, false, name.."Base") + (base or 0) + return baseVal * (1 + (sumMods(modDB, false, name.."Inc") + (inc or 0)) / 100) * sumMods(modDB, true, name.."More") +end + +-- Merge gem modifiers +local function mergeGemMods(modList, gem) + for k, v in pairs(gem.data.base) do + mod_listMerge(modList, k, v) + end + for k, v in pairs(gem.data.quality) do + mod_listMerge(modList, k, m_floor(v * gem.qual)) + end + for k, v in pairs(gem.data.levels[gem.level]) do + mod_listMerge(modList, k, v) + end +end + +-- Merge modifiers for all items, optionally replacing one item +local function mergeItemMods(env, build, repSlot, repItem) + -- Build and merge item mods + env.itemModList = wipeTable(env.itemModList) + for slotName, slot in pairs(build.items.slots) do + local item + if slotName == repSlot then + item = repItem + else + item = build.items.list[slot.selItem] + end + if item then + local armourType = data.itemBases[item.baseName].armour and item.type + for k, v in pairs(item.modList) do + if slotName == "Weapon 1" then + k = k:gsub("weaponX_","weapon1_") + elseif slotName == "Weapon 2" then + k = k:gsub("weaponX_","weapon2_") + end + if armourType and (k == "armourBase" or k == "evasionBase" or k == "energyShieldBase") then + k = armourType.."_"..k + end + mod_listMerge(env.itemModList, k, v) + end + end + end + mod_dbMergeList(env.modDB, env.itemModList) + + -- Find radius jewels + env.radList = wipeTable(env.radList) + for nodeId, node in pairs(build.spec.allocNodes) do + if node.type == "socket" then + local socket, jewel = build.items:GetSocketJewel(nodeId) + if socket.slotName == repSlot then + jewel = repItem + end + if jewel and jewel.radius and jewel.jewelFunc then + t_insert(env.radList, { + rSq = data.jewelRadius[jewel.radius].rad * data.jewelRadius[jewel.radius].rad, + x = node.x, + y = node.y, + func = jewel.jewelFunc, + data = { } + }) + end + end + end +end + +-- Build list of modifiers from the listed tree nodes +local function buildNodeModList(env, nodeList, finishJewels) + -- Initialise radius jewewls + for _, rad in pairs(env.radList) do + wipeTable(rad.data) + end + + -- Add node modifers + local modList = { } + local nodeModList = { } + for _, node in pairs(nodeList) do + -- Build list of mods from this node + for _, mod in pairs(node.mods) do + if mod.list and not mod.extra then + for k, v in pairs(mod.list) do + mod_listMerge(nodeModList, k, v) + end + end + end + + -- Run radius jewels + for _, rad in pairs(env.radList) do + local vX, vY = node.x - rad.x, node.y - rad.y + if vX * vX + vY * vY <= rad.rSq then + rad.func(nodeModList, modList, rad.data) + end + end + + -- Merge with output list + for k, v in pairs(nodeModList) do + mod_listMerge(modList, k, v) + nodeModList[k] = nil + end + if node.passivePointsGranted > 0 then + mod_listMerge(modList, "extraPoints", node.passivePointsGranted) + end + end + + if finishJewels then + -- Finish radius jewels + for _, rad in pairs(env.radList) do + rad.func(nil, modList, rad.data) + end + end + + return modList +end + +-- Generate active namespace table +local function buildSpaceTable(modDB, spaceFlags) + modDB._spaces = { [modDB.global] = false } + if spaceFlags then + for spaceName, val in pairs(spaceFlags) do + if val then + modDB[spaceName] = modDB[spaceName] or { } + if next(modDB[spaceName]) then + modDB._spaces[modDB[spaceName]] = spaceName + end + end + end + end +end + +-- Start watched section +local function startWatch(env, key, ...) + if env.buildWatch then + env.watchers[key] = { _key = key } + env.modDB._activeWatchers[env.watchers[key]] = true + return true + else + if not env.watchers or env.spacesChanged or not env.watchers[key] or env.watchers[key]._flag then + return true + end + for i = 1, select('#', ...) do + if env.watchers[select(i, ...)]._flag then + return true + end + end + end +end + +-- End watched section +local function endWatch(env, key) + if env.buildWatch and env.watchers[key] then + env.modDB._activeWatchers[env.watchers[key]] = nil + end +end + +-- Calculate damage for the given damage type at the given limit ('Min'/'Max') +local function calcDamage(env, output, damageType, limit, ...) + local modDB = env.modDB + local isAttack = (env.mode == "ATTACK") + + local damageTypeLimit = damageType..limit + + -- Calculate base value + local baseVal + if isAttack then + baseVal = getMiscVal(modDB, "weapon1", damageTypeLimit, 0) + sumMods(modDB, false, damageTypeLimit) + else + baseVal = getMiscVal(modDB, "skill", damageTypeLimit, 0) + sumMods(modDB, false, damageTypeLimit) * getMiscVal(modDB, "skill", "damageEff", 1) + end + + -- Build lists of applicable modifier names + local addElemental = isElemental[damageType] + local inc = { damageType.."Inc", "damageInc" } + local more = { damageType.."More", "damageMore" } + local damageTypeStr = "total_"..damageTypeLimit + for i = 1, select('#', ...) do + local dstElem = select(i, ...) + damageTypeStr = damageTypeStr..dstElem + -- Add modifiers for damage types to which this damage is being converted + addElemental = addElemental or isElemental[dstElem] + t_insert(inc, dstElem.."Inc") + t_insert(more, dstElem.."More") + end + if addElemental then + -- Damage is elemental or is being converted to elemental damage, add global elemental modifiers + t_insert(inc, "elemInc") + t_insert(more, "elemMore") + end + + -- Combine modifiers + local damageTypeStrInc = damageTypeStr.."Inc" + local damageTypeStrMore = damageTypeStr.."More" + if startWatch(env, damageTypeStrInc) then + output[damageTypeStrInc] = sumMods(modDB, false, unpack(inc)) + endWatch(env, damageTypeStrInc) + end + if startWatch(env, damageTypeStrMore) then + output[damageTypeStrMore] = sumMods(modDB, true, unpack(more)) + endWatch(env, damageTypeStrMore) + end + + -- Apply modifiers + local val = baseVal * (1 + output[damageTypeStrInc] / 100) * output[damageTypeStrMore] + + -- Apply conversions + if startWatch(env, damageTypeStr.."Conv") then + local add = 0 + local mult = 1 + for _, otherType in pairs(dmgTypeList) do + if otherType ~= damageType then + -- Damage added or converted from the other damage type + local gain = sumMods(modDB, false, otherType.."GainAs"..damageType, otherType.."ConvertTo"..damageType) / 100 + if gain > 0 then + add = add + calcDamage(env, output, otherType, limit, damageType, ...) * gain + end + if not (...) then + -- Some of this damage type is being converted to the other type + -- Not applied to damage being calculated for conversion + local convTo = sumMods(modDB, false, damageType.."ConvertTo"..otherType) / 100 + if convTo > 0 then + mult = mult - convTo + end + end + end + end + output[damageTypeStr.."ConvAdd"] = add + output[damageTypeStr.."ConvMult"] = mult + endWatch(env, damageTypeStr.."Conv") + end + + -- Apply resistances + if not (...) and startWatch(env, damageTypeStr.."Resist") then + if addElemental and env.mode_effective then + output[damageTypeStr.."EffMult"] = 1 - m_min(getMiscVal(modDB, "effective", "elemResist", 0), 75) / 100 + sumMods(modDB, false, damageType.."Pen", "elemPen") / 100 + else + output[damageTypeStr.."EffMult"] = 1 + end + endWatch(env, damageTypeStr.."Resist") + end + + return (val + output[damageTypeStr.."ConvAdd"]) * output[damageTypeStr.."ConvMult"] * ((...) and 1 or sumMods(modDB, true, damageType.."FinalMore") * output[damageTypeStr.."EffMult"]) +end + +-- Initialise environment with skill, input and spec data +local function initEnv(input, build) + local env = { } + + -- Parse gem specification + local gemList = { } + env.gemList = gemList + local errMsg = parseGemSpec(input.skill_spec or "", gemList) + if errMsg then + return nil, errMsg + end + + -- Find active skill gem + local activeGem + for _, gem in ipairs(gemList) do + if not gem.data.support then + if activeGem then + return nil, "Multiple active gems specified:\n"..activeGem.name..", "..gem.name + end + activeGem = gem + end + end + + -- Default attack if no active gem provided + if not activeGem then + activeGem = { + name = "Default Attack", + level = 1, + qual = 0, + data = data.gems._default + } + gemList = { activeGem } + end + env.skillName = activeGem.name + + env.setupFunc = activeGem.data.setupFunc + + -- Build base skill flag set ('attack', 'projectile', etc) + local baseFlags = { } + env.baseFlags = baseFlags + for k, v in pairs(activeGem.data) do + if v == true then + baseFlags[k] = true + end + end + for _, gem in ipairs(gemList) do + if gem.data.support and gem.data.addFlags then + -- Support gem adds flags to supported skills (eg. Remote Mine adds 'mine') + for k in pairs(gem.data.addFlags) do + baseFlags[k] = true + end + end + end + + -- Build skill modifier list + local skillModList = { } + env.skillModList = skillModList + for _, gem in ipairs(gemList) do + if gem.data.support and + (gem.data.attack and not baseFlags.attack) or + (gem.data.spell and not baseFlags.spell) or + (gem.data.melee and not baseFlags.melee) or + (gem.data.projectile and not baseFlags.projectile) or + (gem.data.totem and not baseFlags.totem) or + (gem.data.trap and not baseFlags.trap and not (gem.data.mine and baseFlags.mine)) or + (gem.data.mine and not baseFlags.mine and not (gem.data.trap and baseFlags.trap)) then + -- This support doesn't apply + gem.cantSupport = true + else + mergeGemMods(skillModList, gem) + end + end + + -- Handle multipart skills + if activeGem.data.parts then + input.skill_part = m_max(1, m_min(#activeGem.data.parts, input.skill_part or 1)) + local part = activeGem.data.parts[input.skill_part] + env.skillPartName = part.name + for k, v in pairs(part) do + if v == true then + baseFlags[k] = true + elseif v == false then + baseFlags[k] = nil + end + end + baseFlags.multiPart = #activeGem.data.parts > 1 + else + env.skillPartName = "" + end + + -- Set skill mode + if baseFlags.attack then + env.mode = "ATTACK" + else + env.mode = "SPELL" + end + + -- Process auras and buff skills + local auraSkillModList = { } + local buffSkillModList = { } + env.auraSkillModList = auraSkillModList + env.buffSkillModList = buffSkillModList + for i = 1, 10 do + local spec = input["buff_spec"..i] + if spec and #spec > 0 then + -- Parse gem specification + local gemList = { } + local errMsg = parseGemSpec(spec, gemList) + if errMsg then + return nil, "In aura "..i..": "..errMsg + end + + -- Find active skill + local activeGem + for _, gem in ipairs(gemList) do + if not gem.data.support then + if activeGem then + return nil, "Multiple active gems specified in aura "..i..":\n"..activeGem.name..", "..gem.name + end + activeGem = gem + end + end + + -- Merge modifiers + if activeGem then + if activeGem.data.aura then + mergeGemMods(auraSkillModList, activeGem) + else + mergeGemMods(buffSkillModList, activeGem) + end + end + end + end + + -- Initialise modifier database with base values + local modDB = { } + env.modDB = modDB + env.classId = build.spec.curClassId + local classStats = build.tree.characterData[tostring(env.classId)] + for _, stat in pairs({"str","dex","int"}) do + mod_dbMerge(modDB, "", stat.."Base", classStats["base_"..stat]) + end + local level = input.player_level or 1 + mod_dbMerge(modDB, "", "lifeBase", 38 + level * 12) + mod_dbMerge(modDB, "", "manaBase", 34 + level * 6) + mod_dbMerge(modDB, "", "evasionBase", 53 + level * 3) + mod_dbMerge(modDB, "", "accuracyBase", (level - 1) * 2) + mod_dbMerge(modDB, "", "blockChanceMax", 75) + mod_dbMerge(modDB, "", "powerMax", 3) + mod_dbMerge(modDB, "power", "critChanceInc", 50) + mod_dbMerge(modDB, "", "frenzyMax", 3) + mod_dbMerge(modDB, "frenzy", "speedInc", 4) + mod_dbMerge(modDB, "", "enduranceMax", 3) + mod_dbMerge(modDB, "endurance", "fireResist", 4) + mod_dbMerge(modDB, "endurance", "coldResist", 4) + mod_dbMerge(modDB, "endurance", "lightningResist", 4) + + -- Add bandit mods + if input.misc_banditNormal == "Alira" then + mod_dbMerge(modDB, "", "manaBase", 60) + elseif input.misc_banditNormal == "Kraityn" then + mod_dbMerge(modDB, "", "fireResist", 10) + mod_dbMerge(modDB, "", "coldResist", 10) + mod_dbMerge(modDB, "", "lightningResist", 10) + elseif input.misc_banditNormal == "Oak" then + mod_dbMerge(modDB, "", "lifeBase", 40) + else + mod_dbMerge(modDB, "", "extraPoints", 1) + end + if input.misc_banditCruel == "Alira" then + mod_dbMerge(modDB, "", "castSpeedInc", 5) + elseif input.misc_banditCruel == "Kraityn" then + mod_dbMerge(modDB, "", "attackSpeedInc", 8) + elseif input.misc_banditCruel == "Oak" then + mod_dbMerge(modDB, "", "physicalInc", 16) + else + mod_dbMerge(modDB, "", "extraPoints", 1) + end + if input.misc_banditMerc == "Alira" then + mod_dbMerge(modDB, "", "powerMax", 1) + elseif input.misc_banditMerc == "Kraityn" then + mod_dbMerge(modDB, "", "frenzyMax", 1) + elseif input.misc_banditMerc == "Oak" then + mod_dbMerge(modDB, "", "enduranceMax", 1) + else + mod_dbMerge(modDB, "", "extraPoints", 1) + end + + -- Merge skill mods + mod_dbMergeList(modDB, skillModList) + if baseFlags.multiPart and modDB["part"..input.skill_part] then + -- Merge active skill part mods + mod_dbMergeList(modDB, modDB["part"..input.skill_part]) + end + + -- Merge buff skill modifiers (auras are added later) + for k, v in pairs(buffSkillModList) do + if k:match("^buff_") then + mod_dbMerge(modDB, nil, k:gsub("buff_",""), v) + end + end + + -- Add mods from the input table + for modName, modVal in pairs(input) do + -- Strip namespaces that only the input table uses + local newModName = modName:gsub("^other_","") + mod_dbMerge(modDB, nil, newModName, modVal) + end + + return env +end + +-- Prepare environment for calculations +local function calcSetup(env, output) + local modDB = env.modDB + + local weapon1Type = getMiscVal(modDB, "weapon1", "type", "None") + local weapon2Type = getMiscVal(modDB, "weapon2", "type", "") + if weapon1Type == env.weapon1Type and weapon2Type == env.weapon2Type then + env.spacesChanged = false + else + env.spacesChanged = true + env.weapon1Type = weapon1Type + env.weapon2Type = weapon2Type + + -- Initialise skill flag set + local skillFlags = wipeTable(env.skillFlags) + for k, v in pairs(env.baseFlags) do + skillFlags[k] = v + end + env.skillFlags = skillFlags + + -- Set weapon flags + skillFlags.mainIs1H = true + local weapon1Info = data.weaponTypeInfo[weapon1Type] + if weapon1Info then + if not weapon1Info.oneHand then + skillFlags.mainIs1H = nil + end + if skillFlags.attack then + skillFlags.weapon1Attack = true + if weapon1Info.melee then + skillFlags.bow = nil + skillFlags.projectile = nil + else + skillFlags.melee = nil + end + end + end + local weapon2Info = data.weaponTypeInfo[weapon2Type] + if weapon2Info and skillFlags.mainIs1H then + if skillFlags.attack then + skillFlags.weapon2Attack = true + end + end + + -- Build list of namespaces to search for mods + local skillSpaceFlags = wipeTable(env.skillSpaceFlags) + env.skillSpaceFlags = skillSpaceFlags + if skillFlags.spell then + skillSpaceFlags["spell"] = true + elseif skillFlags.attack then + skillSpaceFlags["attack"] = true + end + if skillFlags.weapon1Attack then + skillSpaceFlags[weapon1Info.space] = true + if weapon1Type ~= "None" then + skillSpaceFlags["weapon"] = true + if skillFlags.mainIs1H then + skillSpaceFlags["weapon1h"] = true + if skillFlags.melee then + skillSpaceFlags["weapon1hMelee"] = true + end + else + skillSpaceFlags["weapon2h"] = true + if skillFlags.melee then + skillSpaceFlags["weapon2hMelee"] = true + end + end + end + end + if skillFlags.melee then + skillSpaceFlags["melee"] = true + elseif skillFlags.projectile then + skillSpaceFlags["projectile"] = true + end + if skillFlags.totem then + skillSpaceFlags["totem"] = true + elseif skillFlags.trap then + skillSpaceFlags["trap"] = true + elseif skillFlags.mine then + skillSpaceFlags["mine"] = true + end + if skillFlags.aoe then + skillSpaceFlags["aoe"] = true + end + if skillFlags.movement then + skillSpaceFlags["movement"] = true + end + -- These are for skill type modifiers such as "Increased Critical Strike Chance with Fire Skills" + if skillFlags.lightning then + skillSpaceFlags["lightning"] = true + elseif skillFlags.cold then + skillSpaceFlags["cold"] = true + elseif skillFlags.fire then + skillSpaceFlags["fire"] = true + elseif skillFlags.chaos then + skillSpaceFlags["chaos"] = true + end + end + if weapon1Type == "None" then + for k, v in pairs(data.unarmedWeap[env.classId]) do + mod_dbMerge(modDB, "weapon1", k, v) + end + end + + -- Set modes + output.mode = env.mode + if env.skillFlags.showAverage then + output.mode_average = true + end + local buffMode = getMiscVal(modDB, "misc", "buffMode", "") + if buffMode == "With buffs" then + env.mode_buffs = true + env.mode_effective = false + elseif buffMode == "Effective DPS with buffs" then + env.mode_buffs = true + env.mode_effective = true + else + env.mode_buffs = false + env.mode_effective = false + end + + -- Reset namespaces + buildSpaceTable(modDB) + + -- Calculate attributes + for _, stat in pairs({"str","dex","int"}) do + output["total_"..stat] = calcVal(modDB, stat) + end + + -- Add attribute bonuses + mod_dbMerge(modDB, "", "lifeBase", output.total_str / 2) + local strDmgBonus = m_floor((output.total_str + getMiscVal(modDB, nil, "dexIntToMeleeBonus", 0)) / 5) + mod_dbMerge(modDB, "melee", "physicalInc", strDmgBonus) + if getMiscVal(modDB, nil, "ironGrip", false) then + mod_dbMerge(modDB, "projectile", "physicalInc", strDmgBonus) + end + if getMiscVal(modDB, nil, "ironWill", false) then + mod_dbMerge(modDB, "spell", "damageInc", strDmgBonus) + end + mod_dbMerge(modDB, "", "accuracyBase", output.total_dex * 2) + if not getMiscVal(modDB, nil, "ironReflexes", false) then + mod_dbMerge(modDB, "", "evasionInc", m_ceil(output.total_dex / 5)) + end + mod_dbMerge(modDB, "", "manaBase", m_ceil(output.total_int / 2)) + mod_dbMerge(modDB, "", "energyShieldInc", m_floor(output.total_int / 5)) + + -- Merge skill-specific modifiers + if modDB["skill:"..env.skillName] then + mod_dbMergeList(modDB, modDB["skill:"..env.skillName]) + end + + -- Build condition list + local condList = { } + env.condList = condList + if env.weapon1Type == "Staff" then + condList["UsingStaff"] = true + end + if env.skillFlags.mainIs1H then + if env.weapon2Type == "Shield" then + condList["UsingShield"] = true + end + end + if modDB.cond then + for k, v in pairs(modDB.cond) do + condList[k] = v + if v then + env.skillFlags[k] = true + end + end + end + if env.mode_buffs then + if modDB.condBuff then + for k, v in pairs(modDB.condBuff) do + condList[k] = v + if v then + env.skillFlags[k] = true + end + end + end + if modDB.condEff and env.mode_effective then + for k, v in pairs(modDB.condEff) do + condList[k] = v + if v then + env.skillFlags[k] = true + end + end + mod_dbMerge(modDB, "condMod", "EnemyShocked_damageMore", 1.5) + condList["EnemyFrozenShockedIgnited"] = condList["EnemyFrozen"] or condList["EnemyShocked"] or condList["EnemyIgnited"] + condList["EnemyElementalStatus"] = condList["EnemyChilled"] or condList["EnemyFrozen"] or condList["EnemyShocked"] or condList["EnemyIgnited"] + end + if not getMiscVal(modDB, nil, "noCrit", false) then + condList["CritInPast8Sec"] = true + end + if env.skillFlags.attack then + condList["AttackedRecently"] = true + elseif env.skillFlags.spell then + condList["CastSpellRecently"] = true + end + if env.skillFlags.movement then + condList["UsedMovementSkillRecently"] = true + end + if env.skillFlags.totem then + condList["SummonedTotemRecently"] = true + end + if env.skillFlags.mine then + condList["DetonatedMinesRecently_"] = true + end + end + + -- Build and merge conditional modifier list + local condModList = { } + env.condModList = condModList + if modDB.condMod then + for k, v in pairs(modDB.condMod) do + local isNot, condName, modName = mod.getCondName(k) + if (isNot and not condList[condName]) or (not isNot and condList[condName]) then + mod_listMerge(condModList, modName, v) + end + end + end + mod_dbMergeList(modDB, env.condModList) + + -- Calculate maximum charges + if getMiscVal(modDB, "buff", "power", false) then + env.skillFlags.havePower = true + output.powerMax = getMiscVal(modDB, nil, "powerMax", 0) + end + if getMiscVal(modDB, "buff", "frenzy", false) then + env.skillFlags.haveFrenzy = true + output.frenzyMax = getMiscVal(modDB, nil, "frenzyMax", 0) + end + if getMiscVal(modDB, "buff", "endurance", false) then + env.skillFlags.haveEndurance = true + output.enduranceMax = getMiscVal(modDB, nil, "enduranceMax", 0) + end + + if env.mode_buffs then + -- Build buff mod list + local buffModList = wipeTable(env.buffModList) + env.buffModList = buffModList + + -- Calculate total charge bonuses + if env.skillFlags.havePower then + for k, v in pairs(modDB.power) do + mod_listMerge(buffModList, k, v * output.powerMax) + end + end + if env.skillFlags.haveFrenzy then + for k, v in pairs(modDB.frenzy) do + mod_listMerge(buffModList, k, v * output.frenzyMax) + end + mod_listMerge(buffModList, "damageMore", 1 + output.frenzyMax * 0.04) + end + if env.skillFlags.haveEndurance then + for k, v in pairs(modDB.endurance) do + mod_listMerge(buffModList, k, v * output.enduranceMax) + end + end + + -- Add other buffs + if env.condList["Onslaught"] then + local effect = m_floor(20 * (1 + sumMods(modDB, false, "onslaughtEffectInc") / 100)) + mod_listMerge(buffModList, "attackSpeedInc", effect) + mod_listMerge(buffModList, "castSpeedInc", effect) + mod_listMerge(buffModList, "movementSpeedInc", effect) + end + + -- Merge buff bonuses + mod_dbMergeList(modDB, buffModList) + end + + -- Merge aura modifiers + local auraEffectMod = 1 + getMiscVal(modDB, nil, "auraEffectInc", 0) / 100 + for k, v in pairs(env.auraSkillModList) do + if not k:match("skill_") then + if mod.isModMult[k] then + mod_dbMerge(modDB, nil, k, m_floor(v * auraEffectMod * 100) / 100) + elseif k:match("Inc$") then + mod_dbMerge(modDB, nil, k, m_floor(v * auraEffectMod)) + else + mod_dbMerge(modDB, nil, k, v * auraEffectMod) + end + end + end +end + +-- Calculate primary stats: damage and defences +local function calcPrimary(env, output) + local modDB = env.modDB + + -- Calculate defences + if startWatch(env, "life") then + if getMiscVal(modDB, nil, "chaosInoculation", false) then + output.total_life = 1 + else + output.total_life = calcVal(modDB, "life") + end + output.total_lifeRegen = sumMods(modDB, false, "lifeRegenBase") + sumMods(modDB, false, "lifeRegenPercent") / 100 * output.total_life + endWatch(env, "life") + end + if startWatch(env, "mana") then + output.total_mana = calcVal(modDB, "mana") + output.total_manaRegen = calcVal(modDB, "manaRegen", output.total_mana * 0.0175) + endWatch(env, "mana") + end + if startWatch(env, "energyShield") then + output.total_energyShield = sumMods(modDB, false, "manaBase") * (1 + sumMods(modDB, false, "energyShieldInc", "defencesInc", "manaInc") / 100) * sumMods(modDB, true, "energyShieldMore", "defencesMore", "manaMore") * getMiscVal(modDB, nil, "manaGainAsES", 0) / 100 + output.total_gear_energyShieldBase = env.itemModList.energyShieldBase or 0 + for _, slot in pairs({"global","Helmet","Body Armour","Gloves","Boots","Shield"}) do + buildSpaceTable(modDB, { [slot] = true }) + local energyShieldBase = getMiscVal(modDB, slot, "energyShieldBase", 0) + if energyShieldBase > 0 then + output.total_energyShield = output.total_energyShield + energyShieldBase * (1 + sumMods(modDB, false, "energyShieldInc", "defencesInc") / 100) * sumMods(modDB, true, "energyShieldMore", "defencesMore") + end + if slot ~= "global" then + output.total_gear_energyShieldBase = output.total_gear_energyShieldBase + energyShieldBase + end + end + buildSpaceTable(modDB) + endWatch(env, "energyShield") + end + if startWatch(env, "otherDef") then + output.total_evasion = 0 + output.total_armour = 0 + output.total_gear_evasionBase = env.itemModList.evasionBase or 0 + output.total_gear_armourBase = env.itemModList.armourBase or 0 + local ironReflexes = getMiscVal(modDB, nil, "ironReflexes", false) + for _, slot in pairs({"global","Helmet","Body Armour","Gloves","Boots","Shield"}) do + buildSpaceTable(modDB, { [slot] = true }) + local evasionBase = getMiscVal(modDB, slot, "evasionBase", 0) + local armourBase = getMiscVal(modDB, slot, "armourBase", 0) + if ironReflexes then + if evasionBase > 0 or armourBase > 0 then + output.total_armour = output.total_armour + (evasionBase + armourBase) * (1 + sumMods(modDB, false, "armourInc", "evasionInc", "armourAndEvasionInc", "defencesInc") / 100) * sumMods(modDB, true, "armourMore", "evasionMore", "defencesMore") + end + else + if evasionBase > 0 then + output.total_evasion = output.total_evasion + evasionBase * (1 + sumMods(modDB, false, "evasionInc", "armourAndEvasionInc", "defencesInc") / 100) * sumMods(modDB, true, "evasionMore", "defencesMore") + end + if armourBase > 0 then + output.total_armour = output.total_armour + armourBase * (1 + sumMods(modDB, false, "armourInc", "armourAndEvasionInc", "defencesInc") / 100) * sumMods(modDB, true, "armourMore", "defencesMore") + end + end + if slot ~= "global" then + output.total_gear_evasionBase = output.total_gear_evasionBase + evasionBase + output.total_gear_armourBase = output.total_gear_armourBase + armourBase + end + end + output.total_blockChance = sumMods(modDB, false, "blockChance") + buildSpaceTable(modDB) + endWatch(env, "otherDef") + end + if startWatch(env, "resist") then + output.total_fireResist = sumMods(modDB, false, "fireResist", "elemResist") - 60 + output.total_coldResist = sumMods(modDB, false, "coldResist", "elemResist") - 60 + output.total_lightningResist = sumMods(modDB, false, "lightningResist", "elemResist") - 60 + if getMiscVal(modDB, nil, "chaosInoculation", false) then + output.total_chaosResist = 100 + else + output.total_chaosResist = sumMods(modDB, false, "chaosResist") - 60 + end + endWatch(env, "resist") + end + + -- Enable skill namespaces + buildSpaceTable(modDB, env.skillSpaceFlags) + + -- Calculate pierce chance + if startWatch(env, "pierce") then + output.total_pierce = m_min(100, sumMods(modDB, false, "pierceChance")) / 100 + endWatch(env, "pierce") + end + if getMiscVal(modDB, nil, "drillneck", false) then + mod_dbMerge(modDB, "projectile", "damageInc", output.total_pierce * 100) + end + + -- Run skill setup function + if env.setupFunc then + env.setupFunc(function(mod, val) mod_dbMerge(modDB, nil, mod, val) end, output) + end + + local isAttack = (env.mode == "ATTACK") + + -- Calculate damage for each damage type + local combMin, combMax = 0, 0 + for _, damageType in pairs(dmgTypeList) do + local min, max + if startWatch(env, damageType) then + min = calcDamage(env, output, damageType, "Min") + max = calcDamage(env, output, damageType, "Max") + output["total_"..damageType.."Min"] = min + output["total_"..damageType.."Max"] = max + output["total_"..damageType.."Avg"] = (min + max) / 2 + endWatch(env, damageType) + else + min = output["total_"..damageType.."Min"] + max = output["total_"..damageType.."Max"] + end + combMin = combMin + min + combMax = combMax + max + end + output.total_combMin = combMin + output.total_combMax = combMax + + if startWatch(env, "dps_crit") then + -- Calculate crit chance, crit multiplier, and their combined effect + if getMiscVal(modDB, nil, "noCrit", false) then + output.total_critChance = 0 + output.total_critMultiplier = 0 + output.total_critEffect = 1 + else + local baseCrit + if isAttack then + baseCrit = getMiscVal(modDB, "weapon1", "critChanceBase", 0) + else + baseCrit = getMiscVal(modDB, "skill", "critChanceBase", 0) + end + output.total_critChance = m_min(calcVal(modDB, "critChance", baseCrit) / 100, 0.95) + if getMiscVal(modDB, nil, "noCritMult", false) then + output.total_critMultiplier = 1 + else + output.total_critMultiplier = 1.5 + sumMods(modDB, false, "critMultiplier") / 100 + end + output.total_critEffect = 1 - output.total_critChance + output.total_critChance * output.total_critMultiplier + end + endWatch(env, "dps_crit") + end + + if startWatch(env, "dps_speed") then + -- Calculate skill speed + if isAttack then + local baseSpeed = getMiscVal(modDB, "weapon1", "attackRate", 0) + output.total_speed = baseSpeed * (1 + sumMods(modDB, false, "speedInc", "attackSpeedInc") / 100) * sumMods(modDB, true, "speedMore", "attackSpeedMore") + else + local baseSpeed = 1 / getMiscVal(modDB, "skill", "castTime", 0) + output.total_speed = baseSpeed * (1 + sumMods(modDB, false, "speedInc", "castSpeedInc") / 100) * sumMods(modDB, true, "speedMore", "castSpeedMore") + end + output.total_time = 1 / output.total_speed + endWatch(env, "dps_speed") + end + + if startWatch(env, "dps_hitChance") then + -- Calculate hit chance + if not isAttack or getMiscVal(modDB, "skill", "noEvade", false) or getMiscVal(modDB, nil, "noEvade", false) or getMiscVal(modDB, "weapon1", "noEvade", false) then + output.total_hitChance = 1 + else + output.total_accuracy = calcVal(modDB, "accuracy") + local targetLevel = getMiscVal(modDB, "misc", "hitMonsterLevel", false) and m_min(getMiscVal(modDB, "monster", "level", 1), #data.evasionTable) or m_min(getMiscVal(modDB, "player", "level", 1), 79) + local rawChance = output.total_accuracy / (output.total_accuracy + (data.evasionTable[targetLevel] / 4) ^ 0.8) * 100 + output.total_hitChance = m_max(m_min(m_floor(rawChance + 0.5) / 100, 0.95), 0.05) + end + endWatch(env, "dps_hitChance") + end + + -- Calculate average damage and final DPS + output.total_avg = (combMin + combMax) / 2 * output.total_critEffect + output.total_dps = output.total_avg * output.total_speed * output.total_hitChance + + -- Calculate mana cost (may be slightly off due to rounding differences) + output.total_manaCost = m_max(0, getMiscVal(modDB, "skill", "manaCostBase", 0) * (1 + sumMods(modDB, false, "manaCostInc") / 100) * sumMods(modDB, true, "manaCostMore") - sumMods(modDB, false, "manaCostBase")) + + -- Calculate skill duration + if startWatch(env, "duration") then + local durationBase = getMiscVal(modDB, "skill", "durationBase", 0) + if durationBase > 0 then + output.total_duration = durationBase * (1 + sumMods(modDB, false, "durationInc") / 100) * sumMods(modDB, true, "durationMore") + end + endWatch(env, "duration") + end + + if env.skillFlags.trap then + output.total_trapCooldown = 3 / (1 + getMiscVal(modDB, nil, "trapCooldownRecoveryInc", 0) / 100) + end + + -- Calculate stun modifiers + if startWatch(env, "stun") then + if getMiscVal(modDB, nil, "stunImmunity", false) then + output.stun_duration = 0 + output.stun_blockDuration = 0 + else + output.stun_duration = 0.35 / (1 + sumMods(modDB, false, "stunRecoveryInc") / 100) + output.stun_blockDuration = 0.35 / (1 + sumMods(modDB, false, "blockRecoveryInc") / 100) + end + local enemyStunThresholdRed = -sumMods(modDB, false, "stunEnemyThresholdInc") + if enemyStunThresholdRed > 75 then + output.stun_enemyThresholdMod = 1 - (75 + (enemyStunThresholdRed - 75) * 25 / (enemyStunThresholdRed - 50)) / 100 + else + output.stun_enemyThresholdMod = 1 - enemyStunThresholdRed / 100 + end + output.stun_enemyDuration = 0.35 * (1 + sumMods(modDB, false, "stunEnemyDurationInc") / 100) + endWatch(env, "stun") + end + + -- Calculate skill DOT components + for _, damageType in pairs(dmgTypeList) do + local baseVal = getMiscVal(modDB, "skill", damageType.."DotBase", 0) + if baseVal > 0 then + env.skillFlags.dot = true + buildSpaceTable(modDB, { + dot = not getMiscVal(modDB, "skill", "dotIsDegen", false), + degen = true, + spell = getMiscVal(modDB, "skill", "dotIsSpell", false), + projectile = env.skillSpaceFlags.projectile, + aoe = env.skillSpaceFlags.aoe, + totem = env.skillSpaceFlags.totem, + trap = env.skillSpaceFlags.trap, + mine = env.skillSpaceFlags.mine, + }) + output["total_"..damageType.."Dot"] = baseVal * (1 + sumMods(modDB, false, "damageInc", damageType.."Inc", isElemental[damageType] and "elemInc" or nil) / 100) * sumMods(modDB, true, "damageMore", damageType.."More", isElemental[damageType] and "elemMore" or nil) + end + end + + -- Calculate bleeding chance and damage + if startWatch(env, "bleed", "physical", "dps_crit") then + output.bleed_chance = m_min(100, sumMods(modDB, false, "bleedChance")) / 100 + if output.total_physicalAvg > 0 then + env.skillFlags.canBleed = true + if output.bleed_chance > 0 then + env.skillFlags.dot = true + env.skillFlags.bleed = true + env.skillFlags.duration = true + buildSpaceTable(modDB, { + dot = true, + degen = true, + bleed = true, + projectile = env.skillSpaceFlags.projectile, + aoe = env.skillSpaceFlags.aoe, + totem = env.skillSpaceFlags.totem, + trap = env.skillSpaceFlags.trap, + mine = env.skillSpaceFlags.mine, + }) + local baseVal = output.total_physicalAvg * output.total_critEffect * 0.1 + output.bleed_dps = baseVal * (1 + sumMods(modDB, false, "damageInc", "physicalInc") / 100) * sumMods(modDB, true, "damageMore", "physicalMore") + output.bleed_duration = 5 * (1 + sumMods(modDB, false, "durationInc") / 100) * sumMods(modDB, true, "durationMore") + end + end + endWatch(env, "bleed") + end + + -- Calculate poison chance and damage + if startWatch(env, "poison", "physical", "chaos", "dps_crit") then + output.poison_chance = m_min(100, sumMods(modDB, false, "poisonChance")) / 100 + if output.total_physicalAvg > 0 or output.total_chaosAvg > 0 then + env.skillFlags.canPoison = true + if output.poison_chance > 0 then + env.skillFlags.dot = true + env.skillFlags.poison = true + env.skillFlags.duration = true + buildSpaceTable(modDB, { + dot = true, + degen = true, + poison = true, + projectile = env.skillSpaceFlags.projectile, + aoe = env.skillSpaceFlags.aoe, + totem = env.skillSpaceFlags.totem, + trap = env.skillSpaceFlags.trap, + mine = env.skillSpaceFlags.mine, + }) + local baseVal = (output.total_physicalAvg + output.total_chaosAvg) * output.total_critEffect * 0.1 + output.poison_dps = baseVal * (1 + sumMods(modDB, false, "damageInc", "chaosInc") / 100) * sumMods(modDB, true, "damageMore", "chaosMore") + output.poison_duration = 2 * (1 + sumMods(modDB, false, "durationInc") / 100) * sumMods(modDB, true, "durationMore") + end + end + endWatch(env, "poison") + end + + -- Calculate ignite chance and damage + if startWatch(env, "ignite", "fire", "dps_crit") then + output.ignite_chance = m_min(100, sumMods(modDB, false, "igniteChance")) / 100 + if output.total_fireAvg > 0 then + env.skillFlags.canIgnite = true + if output.ignite_chance > 0 then + env.skillFlags.dot = true + env.skillFlags.ignite = true + buildSpaceTable(modDB, { + dot = true, + degen = true, + ignite = true, + projectile = env.skillSpaceFlags.projectile, + aoe = env.skillSpaceFlags.aoe, + totem = env.skillSpaceFlags.totem, + trap = env.skillSpaceFlags.trap, + mine = env.skillSpaceFlags.mine, + }) + local baseVal = output.total_fireAvg * output.total_critEffect * 0.2 + output.ignite_dps = baseVal * (1 + sumMods(modDB, false, "damageInc", "fireInc", "elemInc") / 100) * sumMods(modDB, true, "damageMore", "fireMore", "elemMore") + output.ignite_duration = 4 * (1 + getMiscVal(modDB, "ignite", "durationInc", 0) / 100) + end + end + endWatch(env, "ignite") + end +end + +local control = { } + +-- Wipe mod database and repopulate with base mods +local function resetModDB(modDB, base) + for spaceName, spaceMods in pairs(modDB) do + local baseSpace = base[spaceName] + if baseSpace then + for k in pairs(spaceMods) do + spaceMods[k] = baseSpace[k] + end + else + wipeTable(spaceMods) + end + end +end + +-- Generate a function for calculating the effect of some modification to the environment +local function getCalculator(input, build, fullInit, modFunc) + -- Initialise environment + local env, errMsg = initEnv(input, build) + if errMsg then + return + end + + -- Save a copy of the initial mod list + if fullInit then + mergeItemMods(env, build) + env.specModList = buildNodeModList(env, build.spec.allocNodes, true) + mod_dbMergeList(env.modDB, env.specModList) + end + local initModDB = copyTable(env.modDB) + if not fullInit then + mergeItemMods(env, build) + env.specModList = buildNodeModList(env, build.spec.allocNodes, true) + mod_dbMergeList(env.modDB, env.specModList) + end + + -- Run base calculation pass while building watch lists + local base = { } + local outputMeta = { __index = base } + env.watchers = { } + env.buildWatch = true + env.modDB._activeWatchers = { } + calcSetup(env, base) + local baseModDB = copyTable(env.modDB) + baseModDB._activeWatchers = nil + calcPrimary(env, base) + env.buildWatch = false + env.modDB._activeWatchers = nil + + -- Generate list of watched mods + env.watchedModList = { } + for _, watchList in pairs(env.watchers) do + for k, default in pairs(watchList) do + -- Add this watcher to the mod's watcher list + local spaceName, modName = mod.getSpaceName(k) + if not env.watchedModList[spaceName] then + env.watchedModList[spaceName] = { } + end + if not baseModDB[spaceName] then + baseModDB[spaceName] = { } + end + if not initModDB[spaceName] then + initModDB[spaceName] = { } + end + if not env.watchedModList[spaceName][modName] then + env.watchedModList[spaceName][modName] = { baseModDB[spaceName][modName], { } } + end + env.watchedModList[spaceName][modName][2][watchList] = true + if initModDB[spaceName][modName] == nil and baseModDB[spaceName][modName] ~= nil then + -- Ensure that the initial mod list has at least a default value for any modifiers present in the base database + initModDB[spaceName][modName] = default + end + end + end + + local flagged = { } + return function(...) + -- Restore initial mod list + resetModDB(env.modDB, initModDB) + + -- Call function to make modifications to the enviroment + modFunc(env, ...) + + -- Prepare for calculation + local output = setmetatable({ }, outputMeta) + calcSetup(env, output) + + -- Check if any watched variables have changed + local active = false + for spaceName, watchedMods in pairs(env.watchedModList) do + for k, v in pairs(env.modDB[spaceName]) do + local watchedMod = watchedMods[k] + if watchedMod and v ~= watchedMod[1] then + for watchList in pairs(watchedMod[2]) do + watchList._flag = true + flagged[watchList] = true + end + active = true + end + end + end + if not active then + return base + end + + -- Run the calculations + calcPrimary(env, output) + + -- Reset watcher flags + for watchList in pairs(flagged) do + watchList._flag = false + flagged[watchList] = nil + end + + return output + end, base +end + +-- Get calculator for tree node modifiers +function control.getNodeCalculator(input, build) + return getCalculator(input, build, true, function(env, nodeList, remove) + -- Build and merge modifiers for these nodes + local nodeModList = buildNodeModList(env, nodeList) + if remove then + mod_dbUnmergeList(env.modDB, nodeModList) + else + mod_dbMergeList(env.modDB, nodeModList) + end + end) +end + +-- Get calculator for item modifiers +function control.getItemCalculator(input, build) + return getCalculator(input, build, false, function(env, repSlot, repItem) + -- Build and merge item mod list + mergeItemMods(env, build, repSlot, repItem) + + -- Build and merge spec mod list + env.specModList = buildNodeModList(env, build.spec.allocNodes, true) + mod_dbMergeList(env.modDB, env.specModList) + end) +end + +-- Build output for display in the grid +function control.buildOutput(input, output, build) + -- Initialise environment + local env, errMsg = initEnv(input, build) + if errMsg then + setViewMode({ }) + return errMsg + end + + -- Calculate primary stats + mergeItemMods(env, build) + env.specModList = buildNodeModList(env, build.spec.allocNodes, true) + mod_dbMergeList(env.modDB, env.specModList) + calcSetup(env, output) + calcPrimary(env, output) + + -- Add extra display-only stats + for k, v in pairs(env.specModList) do + output["spec_"..k] = v + end + for k, v in pairs(env.itemModList) do + output["gear_"..k] = v + end + output.skill_partName = env.skillPartName + output.total_extraPoints = getMiscVal(env.modDB, nil, "extraPoints", 0) + for _, damageType in pairs(dmgTypeList) do + -- Add damage ranges + if output["total_"..damageType.."Max"] > 0 then + output["total_"..damageType] = formatRound(output["total_"..damageType.."Min"]) .. " - " .. formatRound(output["total_"..damageType.."Max"]) + else + output["total_"..damageType] = 0 + end + + -- Calculate weapon DPS for display + for _, weapon in pairs({"weapon1","weapon2"}) do + local weaponDPS = (getMiscVal(env.modDB, weapon, damageType.."Min", 0) + getMiscVal(env.modDB, weapon, damageType.."Max", 0)) / 2 * getMiscVal(env.modDB, weapon, "attackRate", 1) + output[weapon.."_damageDPS"] = (output[weapon.."damageDPS"] or 0) + weaponDPS + if isElemental[damageType] then + output[weapon.."_elemDPS"] = (output[weapon.."_elemDPS"] or 0) + weaponDPS + end + output[weapon.."_"..damageType.."DPS"] = weaponDPS + end + end + output.total_damage = formatRound(output.total_combMin) .. " - " .. formatRound(output.total_combMax) + + -- Calculate XP modifier + if input.monster_level and input.monster_level > 0 then + local playerLevel = input.player_level or 1 + local diff = m_abs(playerLevel - input.monster_level) - 3 - m_floor(playerLevel / 16) + if diff <= 0 then + output.monster_xp = 1 + else + output.monster_xp = m_max(0.01, ((playerLevel + 5) / (playerLevel + 5 + diff ^ 2.5)) ^ 1.5) + end + end + + -- Configure view mode + setViewMode(env.skillFlags) + + ConPrintf("== Skill Gems ==") + for _, gem in ipairs(env.gemList) do + if gem.cantSupport then + ConPrintf("^1%s %d/%d", gem.name, gem.level, gem.qual) + else + ConPrintf("%s %d/%d", gem.name, gem.level, gem.qual) + end + end + ConPrintf("== Namespaces ==") + mod.listPrint(env.skillSpaceFlags) + ConPrintf("== Skill Mods ==") + mod.listPrint(env.skillModList) + ConPrintf("== Spec Mods ==") + mod.listPrint(env.specModList) + ConPrintf("== Item Mods ==") + mod.listPrint(env.itemModList) + ConPrintf("== Conditions ==") + mod.listPrint(env.condList) + ConPrintf("== Conditional Modifiers ==") + mod.listPrint(env.condModList) + if env.buffModList then + ConPrintf("== Buff Mods ==") + mod.listPrint(env.buffModList) + end +end + +return control diff --git a/CalcsView.lua b/CalcsView.lua new file mode 100644 index 00000000..6e2982d9 --- /dev/null +++ b/CalcsView.lua @@ -0,0 +1,505 @@ +local grid = ... + +local s_format = string.format +local m_abs = math.abs +local m_floor = math.floor +local m_min = math.min +local m_max = math.max +local pairs = pairs +local ipairs = ipairs + +function formatNumSep(val, dec) + dec = dec or 0 + val = val or 0 + local neg = val < 0 + val = m_floor(m_abs(val * 10 ^ dec)) + local str = string.reverse(s_format("%.0f", val)) + if #str < (dec + 1) then + str = str .. string.rep("0", dec + 1 - #str) + end + local ret = "" + local pDec, pThou = dec, 3 + for ci = 1, #str do + local c = str:sub(ci, ci) + ret = c .. ret + if pDec > 0 then + pDec = pDec - 1 + if pDec == 0 then + ret = "." .. ret + end + else + pThou = pThou - 1 + if pThou == 0 and ci < #str then + ret = "," .. ret + pThou = 3 + end + end + end + return (neg and "-" or "") .. ret +end +function getFormatNumSep(dec) + return function(val) + return formatNumSep(val, dec) + end +end + +function formatRound(val, dec) + dec = dec or 0 + return m_floor(val * 10 ^ dec + 0.5) / 10 ^ dec +end +function getFormatRound(dec) + return function(val) + return formatRound(val, dec) + end +end + +function formatPercent(val, dec) + dec = dec or 0 + return m_floor((val or 0) * 100 * 10 ^ dec) / 10 ^ dec .. "%" +end +function getFormatPercent(dec) + return function(val) + return formatPercent(val, dec) + end +end + +function formatSec(val) + if val == 0 then + return "0s" + else + return s_format("%.2fs", val) + end +end + +local function mkField(x, y, fieldType, name, format, width, list) + local isFunc = type(format) == "function" + grid:SetElem(x, y, { + type = fieldType, + name = name, + format = (isFunc or not format) and "number" or format, + formatFunc = isFunc and format, + align = (format == "string" or format == "choice") and "LEFT" or "RIGHT", + width = width, + list = list, + }) +end +local function mkFieldWithLabel(x, y, fieldType, label, name, format, width, list) + grid:SetElem(x, y, { + type = "label", + text = label, + align = "RIGHT" + }) + if type(name) == "table" then + for i, n in ipairs(name) do + if n then + mkField(x + i, y, fieldType, n, format) + end + end + else + mkField(x + 1, y, fieldType, name, format, width, list) + end +end +local function mkFieldTable(x, y, tbl) + for i, v in ipairs(tbl) do + if #v == 1 then + if type(v[1]) == "table" then + for c, l in ipairs(v[1]) do + grid:SetElem(x + c - 1, y + i - 1, { type = "label", text = l, align = c == 1 and "RIGHT" or "CENTER" }) + end + else + grid:SetElem(x, y + i - 1, { type = "label", text = v[1], align = "RIGHT" }) + end + elseif #v > 1 then + mkFieldWithLabel(x, y + i - 1, unpack(v)) + end + end +end + +local function fieldNames(pre, suf, spec) + return { + spec:match("p") and (pre.."_physical"..suf) or false, + spec:match("l") and (pre.."_lightning"..suf) or false, + spec:match("c") and (pre.."_cold"..suf) or false, + spec:match("f") and (pre.."_fire"..suf) or false, + spec:match("h") and (pre.."_chaos"..suf) or false, + spec:match("a") and (pre.."_damage"..suf) or false, + spec:match("e") and (pre.."_elem"..suf) or false + } +end + +local columnWidths = { + 120, 60, + 150, 60, + 150, 60, + 160, 90, 90, 90, 90, 90, 90, 70 +} + +local columns = { } + +columns[1] = { + { + { "Player:" }, + { "input", "Level:", "player_level" }, + { "output", "Gear Strength:", "gear_strBase" }, + { "output", "Gear Dexterity:", "gear_dexBase" }, + { "output", "Gear Intelligence:", "gear_intBase" }, + { "output", "^xFF7700Strength^7:", "total_str" }, + { "output", "^x33FF33Dexterity^7:", "total_dex" }, + { "output", "^x7777FFIntelligence^7:", "total_int" }, + { }, + { "Monsters:" }, + { "input", "Monster level:", "monster_level" }, + { "output", "Experience:", "monster_xp", formatPercent }, + { }, + { "Life:" }, + { "output", "Spec +:", "spec_lifeBase" }, + { "output", "Spec %:", "spec_lifeInc" }, + { "output", "Gear +:", "gear_lifeBase" }, + { "output", "Gear %:", "gear_lifeInc" }, + { "output", "Total:", "total_life", formatRound }, + { "output", "Spec Regen %:", "spec_lifeRegenPercent" }, + { "output", "Gear Regen +:", "gear_lifeRegenBase" }, + { "output", "Gear Regen %:", "gear_lifeRegenPercent" }, + { "output", "Total Regen:", "total_lifeRegen", getFormatRound(1) }, + { }, + { "Mana:" }, + { "output", "Spec +:", "spec_manaBase" }, + { "output", "Spec %:", "spec_manaInc" }, + { "output", "Gear +:", "gear_manaBase" }, + { "output", "Gear %:", "gear_manaInc" }, + { "output", "Total:", "total_mana", formatRound }, + { "output", "Spec Regen %:", "spec_manaRegenInc" }, + { "output", "Gear Regen +:", "gear_manaRegenBase" }, + { "output", "Gear Regen %:", "gear_manaRegenInc" }, + { "output", "Total Regen:", "total_manaRegen", getFormatRound(1) }, + { }, + { "Auras and Buffs:" }, + { "input", "Skill 1:", "buff_spec1", "string", 2 }, + { "input", "Skill 2:", "buff_spec2", "string", 2 }, + { "input", "Skill 3:", "buff_spec3", "string", 2 }, + { "input", "Skill 4:", "buff_spec4", "string", 2 }, + { "input", "Skill 5:", "buff_spec5", "string", 2 }, + { "input", "Skill 6:", "buff_spec6", "string", 2 }, + { "input", "Skill 7:", "buff_spec7", "string", 2 }, + { "input", "Skill 8:", "buff_spec8", "string", 2 }, + { "input", "Skill 9:", "buff_spec9", "string", 2 }, + { "input", "Skill 10:", "buff_spec10", "string", 2 }, + } +} + +columns[3] = { + { + { "Energy Shield:" }, + { "output", "Spec +:", "spec_energyShieldBase" }, + { "output", "Spec %:", "spec_energyShieldInc" }, + { "output", "Gear +:", "total_gear_energyShieldBase" }, + { "output", "Gear %:", "gear_energyShieldInc" }, + { "output", "Total:", "total_energyShield", formatRound }, + { "output", "Recharge rate:", "total_energyShieldRecharge", getFormatRound(1) }, + { "output", "Recharge delay:", "total_energyShieldRechargeDelay", formatSec }, + { }, + { "Evasion:" }, + { "output", "Spec +:", "spec_evasionBase" }, + { "output", "Spec %:", "spec_evasionInc" }, + { "output", "Gear +:", "total_gear_evasionBase" }, + { "output", "Gear %:", "gear_evasionInc" }, + { "output", "Total:", "total_evasion", formatRound }, + { }, + { "Armour:" }, + { "output", "Spec +:", "spec_armourBase" }, + { "output", "Spec %:", "spec_armourInc" }, + { "output", "Gear +:", "total_gear_armourBase" }, + { "output", "Gear %:", "gear_armourInc" }, + { "output", "Total:", "total_armour", formatRound }, + { }, + { "Misc:" }, + { "input", "Normal Bandit:", "misc_banditNormal", "choice", 1, { "None", "Alira", "Kraityn", "Oak" } }, + { "input", "Cruel Bandit:", "misc_banditCruel", "choice", 1, { "None", "Alira", "Kraityn", "Oak" } }, + { "input", "Merciless Bandit:", "misc_banditMerc", "choice", 1, { "None", "Alira", "Kraityn", "Oak" } }, + { "input", "Always on Low Life?", "cond_LowLife", "check" }, + { "input", "Always on Full Life?", "cond_FullLife", "check" }, + } +} + +columns[5] = { + { + { "Buffs:" }, + { "input", "Power Charges?", "buff_power", "check" }, + }, { + flag = "havePower", + { "output", "Max Power:", "powerMax" }, + }, { + { "input", "Frenzy Charges?", "buff_frenzy", "check" }, + }, { + flag = "haveFrenzy", + { "output", "Max Frenzy:", "frenzyMax" }, + }, { + { "input", "Endurance Charges?", "buff_endurance", "check" }, + }, { + flag = "haveEndurance", + { "output", "Max Endurance:", "enduranceMax" }, + }, { + { "input", "Onslaught?", "condBuff_Onslaught", "check" }, + { "input", "Fortify?", "condBuff_Fortify", "check" }, + { "input", "Using a Flask?", "condBuff_UsingFlask", "check" }, + }, { + { }, + { "For Effective DPS:" }, + { "input", "Enemy is Bleeding?", "condEff_EnemyBleeding", "check" }, + { "input", "Enemy is Poisoned?", "condEff_EnemyPoisoned", "check" }, + { "input", "Enemy is Burning?", "condEff_EnemyBurning", "check" }, + { "input", "Enemy is Ignited?", "condEff_EnemyIgnited", "check" }, + { "input", "Enemy is Chilled?", "condEff_EnemyChilled", "check" }, + { "input", "Enemy is Frozen?", "condEff_EnemyFrozen", "check" }, + { "input", "Enemy is Shocked?", "condEff_EnemyShocked", "check" }, + { "input", "Enemy Elem. Resist:", "effective_elemResist" }, + { }, + { "Crit Chance:" }, + }, { + flag = "attack", + { "output", "Weapon Crit %:", "gear_weap1_critChanceBase" }, + }, { + { "output", "Spec Global Crit %:", "spec_critChanceInc" }, + { "output", "Gear Global Crit %:", "gear_global_critChanceInc" }, + }, { + flag = "spell", + { "output", "Spec Spell Crit %:", "spec_spell_critChanceInc" }, + { "output", "Gear Spell Crit %:", "gear_spell_critChanceInc" }, + }, { + flag = "melee", + { "output", "Spec Melee Crit %:", "spec_melee_critChanceInc" }, + }, { + flag = "totem", + { "output", "Spec Totem Crit %:", "spec_totem_critChanceInc" }, + }, { + flag = "trap", + { "output", "Spec Trap Crit %:", "spec_trap_critChanceInc" }, + }, { + flag = "mine", + { "output", "Spec Mine Crit %:", "spec_mine_critChanceInc" }, + }, { + { "output", "Crit Chance:", "total_critChance", getFormatPercent(2) }, + { "output", "Spec Global Multi %:", "spec_critMultiplier" }, + { "output", "Gear Global Multi %:", "gear_critMultiplier" }, + }, { + flag = "spell", + { "output", "Spec Spell Multi %:", "spec_spell_critMultiplier" }, + }, { + flag = "melee", + { "output", "Spec Melee Multi %:", "spec_melee_critMultiplier" }, + }, { + flag = "totem", + { "output", "Spec Totem Multi %:", "spec_totem_critMultiplier" }, + }, { + flag = "trap", + { "output", "Spec Trap Multi %:", "spec_trap_critMultiplier" }, + }, { + flag = "mine", + { "output", "Spec Mine Multi %:", "spec_mine_critMultiplier" }, + }, { + { "output", "Multiplier:", "total_critMultiplier", formatPercent }, + }, { + flag = "attack", + { }, + { "Accuracy:" }, + { "output", "Spec Accuracy+:", "spec_accuracyBase" }, + { "output", "Spec Accuracy %:", "spec_accuracyInc" }, + { "output", "Gear Accuracy+:", "gear_accuracyBase" }, + { "output", "Gear Accuracy %:", "gear_accuracyInc" }, + { "output", "Total Accuracy:", "total_accuracy", formatRound }, + { "input", "Use Monster Level?", "misc_hitMonsterLevel", "check" }, + { "output", "Chance to Hit:", "total_hitChance", formatPercent }, + }, { + { }, + { "Stun:" }, + { "output", "Stun Duration on You:", "stun_duration", formatSec }, + { "output", "Block Duration on You:", "stun_blockDuration", formatSec }, + { "output", "Duration on Enemies:", "stun_enemyDuration", formatSec }, + { "output", "Enemy Threshold Mod:", "stun_enemyThresholdMod", formatPercent }, + } +} + +columns[7] = { + { + { "input", "Skill:", "skill_spec", "string", 7 }, + }, { + flag = "multiPart", + { "input", "Skill Part #:", "skill_part" }, + { "output", "Part:", "skill_partName", "string", 2 }, + }, { + { }, + { "input", "Mode:", "misc_buffMode", "choice", 2, { "Unbuffed", "With buffs", "Effective DPS with buffs" } }, + { }, + }, { + flag = "attack", + { { "Attack:", "Physical", "Lightning", "Cold", "Fire", "Chaos", "Combined", "Elemental" } }, + }, { + flag = "weapon1Attack", + { "output", "Main Hand:", "gear_weapon1_name", "string", 3 }, + { "output", "Weapon Min:", fieldNames("gear_weapon1", "Min", "plcfh") }, + { "output", "Weapon Max:", fieldNames("gear_weapon1", "Max", "plcfh") }, + { "output", "Weapon APS:", "gear_weapon1_attackRate" }, + { "output", "Weapon DPS:", fieldNames("weapon1", "DPS", "plcfhae"), getFormatRound(2) }, + }, { + flag = "weapon2Attack", + { "output", "Off Hand:", "gear_weapon2_name", "string", 3 }, + { "output", "Weapon Min:", fieldNames("gear_weapon2", "Min", "plcfh") }, + { "output", "Weapon Max:", fieldNames("gear_weapon2", "Max", "plcfh") }, + { "output", "Weapon APS:", "gear_weapon2_attackRate" }, + { "output", "Weapon DPS:", fieldNames("weaponon2", "DPS", "plcfhae"), getFormatRound(2) }, + }, { + flag = "attack", + { "output", "Spec Attack Dmg %:", fieldNames("spec_attack", "Inc", "pa") }, + { "output", "Spec Weapon Dmg %:", fieldNames("spec_weapon", "Inc", "plcfae") }, + { "output", "Gear Weapon Dmg %:", fieldNames("gear_weapon", "Inc", "plcfae") }, + }, { + flag = "spell", + { { "Spell:", "Physical", "Lightning", "Cold", "Fire", "Chaos", "Combined", "Elemental" } }, + { "output", "Spec Spell Dmg %:", fieldNames("spec_spell", "Inc", "a") }, + { "output", "Gear Spell Dmg %:", fieldNames("gear_spell", "Inc", "a") }, + }, { + flag = "projectile", + { "output", "Spec Projectile Dmg %:", fieldNames("spec_projectile", "Inc", "a") }, + { "output", "Gear Projectile Dmg %:", fieldNames("gear_projectile", "Inc", "a") }, + }, { + flag = "aoe", + { "output", "Spec Area Dmg %:", fieldNames("spec_aoe", "Inc", "a") }, + { "output", "Gear Area Dmg %:", fieldNames("gear_aoe", "Inc", "a") }, + }, { + flag = "totem", + { "output", "Spec Totem Dmg %:", fieldNames("spec_totem", "Inc", "a") }, + { "output", "Gear Totem Dmg %:", fieldNames("gear_totem", "Inc", "a") }, + }, { + flag = "trap", + { "output", "Spec Trap Dmg %:", fieldNames("spec_trap", "Inc", "a") }, + { "output", "Gear Trap Dmg %:", fieldNames("gear_trap", "Inc", "a") }, + }, { + flag = "mine", + { "output", "Spec Mine Dmg %:", fieldNames("spec_mine", "Inc", "a") }, + { "output", "Gear Mine Dmg %:", fieldNames("gear_mine", "Inc", "a") }, + }, { + { "output", "Spec Global %:", fieldNames("spec", "Inc", "plcfhe") }, + { "output", "Gear Global %:", fieldNames("gear", "Inc", "plcfhae") }, + }, { + flag = "attack", + { "output", "Gear Attack Min+:", fieldNames("gear_attack", "Min", "plcfh") }, + { "output", "Gear Attack Max+:", fieldNames("gear_attack", "Max", "plcfh") }, + }, { + flag = "spell", + { "output", "Gear Spell Min+:", fieldNames("gear_spell", "Min", "plcfh") }, + { "output", "Gear Spell Max+:", fieldNames("gear_spell", "Max", "plcfh") }, + }, { + flag = "attack", + { "output", "Spec Attack Speed %:", "spec_attackSpeedInc" }, + { "output", "Gear Attack Speed %:", "gear_attackSpeedInc" }, + { "output", "Spec Attack&Cast Sp. %:", "spec_speedInc" }, + { "output", "Gear Attack&Cast Sp. %:", "gear_speedInc" }, + { "output", "Attack Damage:", fieldNames("total", "", "plcfha") }, + { "output", "Average Damage:", "total_avg", getFormatRound(1) }, + { "output", "Attack Speed:", "total_speed", getFormatRound(2) }, + { "output", "Attack Time:", "total_time", getFormatRound(2) }, + { "output", "Attack DPS:", "total_dps", getFormatRound(1) }, + }, { + flag = "spell", + { "output", "Spec Cast Speed %:", "spec_castSpeedInc" }, + { "output", "Gear Cast Speed %:", "gear_castSpeedInc" }, + { "output", "Spec Attack&Cast Sp. %:", "spec_speedInc" }, + { "output", "Gear Attack&Cast Sp. %:", "gear_speedInc" }, + { "output", "Spell Damage:", fieldNames("total", "", "plcfha") }, + { "output", "Average Damage:", "total_avg", getFormatRound(1) }, + { "output", "Cast Rate:", "total_speed", getFormatRound(2) }, + { "output", "Cast Time:", "total_time", getFormatRound(2) }, + { "output", "Spell DPS:", "total_dps", getFormatRound(1) }, + }, { + flag = "cast", + { "output", "Secondary Damage:", fieldNames("total", "", "plcfha") }, + { "output", "Average Damage:", "total_avg", getFormatRound(1) }, + }, { + { "output", "Mana Cost:", "total_manaCost", formatRound } + }, { + flag = "projectile", + { "output", "Spec Pierce Chance %:", "spec_pierceChance" }, + { "output", "Gear Pierce Chance %:", "gear_pierceChance" }, + { "output", "Pierce Chance:", "total_pierce", formatPercent }, + }, { + flag = "duration", + { "output", "Spec Duration %:", "spec_durationInc" }, + { "output", "Skill Duration:", "total_duration", formatSec }, + }, { + flag = "trap", + { "output", "Trap Cooldown:", "total_trapCooldown", formatSec }, + }, { + flag = "dot", + { "output", "Spec DoT Dmg %:", fieldNames("spec_dot", "Inc", "pfa") }, + { "output", "Gear DoT Dmg %:", fieldNames("gear_dot", "Inc", "pfa") }, + { "output", "DoT:", fieldNames("total", "Dot", "plcfh"), getFormatRound(1) }, + }, { + flag = "canBleed", + { "output", "Spec Bleed Chance %:", "spec_bleedChance" }, + { "output", "Gear Bleed Chance %:", "gear_bleedChance" }, + { "input", "Other Bleed Chance %:", "other_bleedChance" }, + }, { + flag = "bleed", + { "output", "Bleed Chance:", "bleed_chance", formatPercent }, + { "output", "Bleed DPS:", "bleed_dps", getFormatRound(1) }, + { "output", "Bleed Duration:", "bleed_duration", formatSec }, + }, { + flag = "canPoison", + { "output", "Spec Poison Chance %:", "spec_poisonChance" }, + { "output", "Gear Poison Chance %:", "gear_poisonChance" }, + { "input", "Other Poison Chance %:", "other_poisonChance" }, + }, { + flag = "poison", + { "output", "Spec Poison Dmg %:", "spec_poison_damageInc" }, + { "output", "Poison Chance:", "poison_chance", formatPercent }, + { "output", "Poison DPS:", "poison_dps", getFormatRound(1) }, + { "output", "Poison Duration:", "poison_duration", formatSec }, + }, { + flag = "canIgnite", + { "output", "Spec Ignite Chance %:", "spec_igniteChance" }, + { "output", "Gear Ignite Chance %:", "gear_igniteChance" }, + { "input", "Other Ignite Chance %:", "other_igniteChance" }, + }, { + flag = "ignite", + { "output", "Ignite Chance:", "ignite_chance", formatPercent }, + { "output", "Ignite DPS:", "ignite_dps", getFormatRound(1) }, + { "output", "Ignite Duration:", "ignite_duration", formatSec }, + } +} + +local curFlags + +return function(newFlags) + if curFlags then + local noNewFlags = true + local sub = copyTable(curFlags) + for flag in pairs(newFlags) do + if curFlags[flag] then + sub[flag] = nil + else + noNewFlags = false + break + end + end + if noNewFlags and not next(sub) then + return + end + end + curFlags = copyTable(newFlags) + + grid:Clear() + + for colX, colTables in pairs(columns) do + local y = 1 + for _, data in ipairs(colTables) do + if not data.flag or curFlags[data.flag] then + mkFieldTable(colX, y, data) + y = y + #data + end + end + end + + for col, width in ipairs(columnWidths) do + grid:SetColWidth(col, width) + end +end \ No newline at end of file diff --git a/Common.lua b/Common.lua new file mode 100644 index 00000000..ee409bfa --- /dev/null +++ b/Common.lua @@ -0,0 +1,408 @@ +common = { } + +common.curl = require("lcurl") +common.xml = require("xml") +common.json = require("dkjson") +common.base64 = require("base64") + +function common.controlsInput(host, inputEvents) + for id, event in ipairs(inputEvents) do + if event.type == "KeyDown" then + if host.selControl then + if host.selControl:OnKeyDown(event.key, event.doubleClick) then + host.selControl = nil + end + inputEvents[id] = nil + elseif event.key == "LEFTBUTTON" then + local cx, cy = GetCursorPos() + for _, control in pairs(host.controls) do + if control.IsMouseOver and control:IsMouseOver() and control.OnKeyDown then + if not control:OnKeyDown(event.key, event.doubleClick) then + host.selControl = control + end + inputEvents[id] = nil + break + end + end + end + elseif event.type == "KeyUp" then + if host.selControl then + if host.selControl:OnKeyUp(event.key) then + host.selControl = nil + end + inputEvents[id] = nil + end + elseif event.type == "Char" then + if host.selControl then + if host.selControl.OnChar and host.selControl:OnChar(event.key) then + host.selControl = nil + end + inputEvents[id] = nil + end + end + end +end + +function common.controlsDraw(host, ...) + for _, control in pairs(host.controls) do + if control ~= host.selControl then + control:Draw(...) + end + end + if host.selControl then + host.selControl:Draw(...) + end + +end + +common.newEditField = require("simplegraphic/editfield") + +local editMeta = { } +editMeta.__index = editMeta +function editMeta:IsMouseOver() + if self.hidden then + return false + end + self.edit.x = type(self.x) == "function" and self:x() + 2 or self.x + 2 + self.edit.y = type(self.y) == "function" and self:y() + 2 or self.y + 2 + return self.edit:IsMouseOver() +end +function editMeta:OnKeyDown(key, doubleClick) + self.edit.x = type(self.x) == "function" and self:x() + 2 or self.x + 2 + self.edit.y = type(self.y) == "function" and self:y() + 2 or self.y + 2 + self.active = not self.edit:OnKeyDown(key, doubleClick) + return not self.active +end +function editMeta:OnKeyUp(key) + self.edit.x = type(self.x) == "function" and self:x() + 2 or self.x + 2 + self.edit.y = type(self.y) == "function" and self:y() + 2 or self.y + 2 + self.active = not self.edit:OnKeyUp(key) + return not self.active +end +function editMeta:OnChar(key) + self.edit.x = type(self.x) == "function" and self:x() + 2 or self.x + 2 + self.edit.y = type(self.y) == "function" and self:y() + 2 or self.y + 2 + self.active = not self.edit:OnChar(key) + return not self.active +end +function editMeta:Draw() + if self.hidden then + return + end + local x = type(self.x) == "function" and self:x() or self.x + local y = type(self.y) == "function" and self:y() or self.y + local enabled = not self.edit.enableFunc or self.edit.enableFunc() + local mOver = self:IsMouseOver() + if not enabled then + SetDrawColor(0.33, 0.33, 0.33) + elseif mOver then + SetDrawColor(1, 1, 1) + else + SetDrawColor(0.5, 0.5, 0.5) + end + DrawImage(nil, x, y, self.width, self.height) + if not enabled then + SetDrawColor(0, 0, 0) + elseif self.active or mOver then + SetDrawColor(0.15, 0.15, 0.15) + else + SetDrawColor(0, 0, 0) + end + DrawImage(nil, x + 1, y + 1, self.width - 2, self.height - 2) + self.edit.x = x + 2 + self.edit.y = y + 2 + self.edit:Draw(nil, nil, nil, not self.active) +end +function editMeta:SetText(text) + self.edit:SetText(text) +end +function common.newEditControl(x, y, width, height, ...) + local control = { } + control.x = x + control.y = y + control.width = width + control.height = height + control.edit = common.newEditField(...) + control.edit.width = width - 4 + control.edit.height = height - 4 + control.edit.leader = "" + return setmetatable(control, editMeta) +end + +local buttonMeta = { } +buttonMeta.__index = buttonMeta +function buttonMeta:IsMouseOver() + if self.hidden then + return false + end + local x = type(self.x) == "function" and self:x() or self.x + local y = type(self.y) == "function" and self:y() or self.y + local cx, cy = GetCursorPos() + return cx >= x and cy >= y and cx < x + self.width and cy < y + self.height +end +function buttonMeta:OnKeyDown(key) + if self.enableFunc and not self.enableFunc() then + return true + end + if key == "LEFTBUTTON" then + self.clicked = true + end + return false +end +function buttonMeta:OnKeyUp(key) + if self.enableFunc and not self.enableFunc() then + return true + end + if key == "LEFTBUTTON" then + if self:IsMouseOver() then + self.onClick() + end + end + self.clicked = false + return true +end +function buttonMeta:Draw() + if self.hidden then + return + end + local x = type(self.x) == "function" and self:x() or self.x + local y = type(self.y) == "function" and self:y() or self.y + local enabled = not self.enableFunc or self.enableFunc() + local mOver = self:IsMouseOver() + if not enabled then + SetDrawColor(0.33, 0.33, 0.33) + elseif mOver then + SetDrawColor(1, 1, 1) + else + SetDrawColor(0.5, 0.5, 0.5) + end + DrawImage(nil, x, y, self.width, self.height) + if not enabled then + SetDrawColor(0, 0, 0) + elseif self.clicked and mOver then + SetDrawColor(0.5, 0.5, 0.5) + elseif mOver then + SetDrawColor(0.33, 0.33, 0.33) + else + SetDrawColor(0, 0, 0) + end + DrawImage(nil, x + 1, y + 1, self.width - 2, self.height - 2) + if enabled then + SetDrawColor(1, 1, 1) + else + SetDrawColor(0.33, 0.33, 0.33) + end + DrawString(x + self.width / 2, y + 2, "CENTER_X", self.height - 4, "VAR", self.label) +end +function common.newButton(x, y, width, height, label, onClick, enableFunc) + local control = { } + control.x = x + control.y = y + control.width = width + control.height = height + control.label = label + control.onClick = onClick + control.enableFunc = enableFunc + return setmetatable(control, buttonMeta) +end + +local dropDownMeta = { } +dropDownMeta.__index = dropDownMeta +function dropDownMeta:IsMouseOver() + if self.hidden then + return false + end + local x = type(self.x) == "function" and self:x() or self.x + local y = type(self.y) == "function" and self:y() or self.y + local cx, cy = GetCursorPos() + local dropExtra = self.dropped and (self.height - 4) * #self.list + 2 or 0 + return cx >= x and cy >= y and cx < x + self.width and cy < y + self.height + dropExtra, cy < y + self.height +end +function dropDownMeta:OnKeyDown(key) + if self.enableFunc and not self.enableFunc() then + return true + end + if key == "LEFTBUTTON" then + local all, body = self:IsMouseOver() + if not all or (self.dropped and body) then + self.dropped = false + return true + end + self.dropped = true + return false + elseif key == "ESCAPE" then + self.dropped = false + return true + end + return false +end +function dropDownMeta:OnKeyUp(key) + if self.enableFunc and not self.enableFunc() then + return true + end + if key == "LEFTBUTTON" then + local all, body = self:IsMouseOver() + if not all then + self.dropped = false + return true + elseif not body then + local y = type(self.y) == "function" and self:y() or self.y + local sel = math.max(1, math.floor((select(2,GetCursorPos()) - y - self.height) / (self.height - 4)) + 1) + self.sel = sel + if self.selFunc then + self.selFunc(sel, self.list[sel]) + end + self.dropped = false + return true + end + end + return false +end +function dropDownMeta:Draw() + if self.hidden then + return false + end + local x = type(self.x) == "function" and self:x() or self.x + local y = type(self.y) == "function" and self:y() or self.y + local enabled = not self.enableFunc or self.enableFunc() + local mOver, mOverBody = self:IsMouseOver() + local dropExtra = (self.height - 4) * #self.list + 4 + if not enabled then + SetDrawColor(0.33, 0.33, 0.33) + elseif mOver or self.dropped then + SetDrawColor(1, 1, 1) + else + SetDrawColor(0.5, 0.5, 0.5) + end + DrawImage(nil, x, y, self.width, self.height) + if self.dropped then + DrawImage(nil, x, y + self.height, self.width, dropExtra) + end + if not enabled then + SetDrawColor(0, 0, 0) + elseif self.dropped then + SetDrawColor(0.5, 0.5, 0.5) + elseif mOver then + SetDrawColor(0.33, 0.33, 0.33) + else + SetDrawColor(0, 0, 0) + end + DrawImage(nil, x + 1, y + 1, self.width - 2, self.height - 2) + if not enabled then + SetDrawColor(0.33, 0.33, 0.33) + elseif mOver or self.dropped then + SetDrawColor(1, 1, 1) + else + SetDrawColor(0.5, 0.5, 0.5) + end + local x1 = x + self.width - self.height / 2 - self.height / 4 + local x2 = x1 + self.height / 2 + local y1 = y + self.height / 4 + local y2 = y1 + self.height / 2 + DrawImageQuad(nil, x1, y1, x2, y1, (x1+x2)/2, y2, (x1+x2)/2, y2) + if self.dropped then + SetDrawColor(0, 0, 0) + DrawImage(nil, x + 1, y + self.height + 1, self.width - 2, dropExtra - 2) + end + if enabled then + SetDrawColor(1, 1, 1) + else + SetDrawColor(0.66, 0.66, 0.66) + end + DrawString(x + 2, y + 2, "LEFT", self.height - 4, "VAR", self.list[self.sel] or "") + if self.dropped then + self.hoverSel = mOver and math.floor((select(2,GetCursorPos()) - y - self.height) / (self.height - 4)) + 1 + if self.hoverSel and self.hoverSel < 1 then + self.hoverSel = nil + end + for index, val in ipairs(self.list) do + local y = y + self.height + 2 + (index - 1) * (self.height - 4) + if index == self.hoverSel then + SetDrawColor(0.5, 0.4, 0.3) + DrawImage(nil, x + 2, y, self.width - 4, self.height - 4) + end + if index == self.hoverSel or index == self.sel then + SetDrawColor(1, 1, 1) + else + SetDrawColor(0.66, 0.66, 0.66) + end + DrawString(x + 2, y, "LEFT", self.height - 4, "VAR", StripEscapes(val)) + end + end +end +function dropDownMeta:SelByValue(val) + for index, listVal in ipairs(self.list) do + if listVal == val then + self.sel = index + return + end + end +end +function common.newDropDown(x, y, width, height, list, selFunc, enableFunc) + local control = { } + control.x = x + control.y = y + control.width = width + control.height = height + control.list = list or { } + control.sel = 1 + control.selFunc = selFunc + control.enableFunc = enableFunc + return setmetatable(control, dropDownMeta) +end + +function common.drawPopup(r, g, b, fmt, ...) + local screenW, screenH = GetScreenSize() + SetDrawColor(0, 0, 0, 0.5) + DrawImage(nil, 0, 0, screenW, screenH) + local txt = string.format(fmt, ...) + local w = DrawStringWidth(20, "VAR", txt) + 20 + local h = (#txt:gsub("[^\n]","") + 2) * 20 + local ox = (screenW - w) / 2 + local oy = (screenH - h) / 2 + SetDrawColor(1, 1, 1) + DrawImage(nil, ox, oy, w, h) + SetDrawColor(r, g, b) + DrawImage(nil, ox + 2, oy + 2, w - 4, h - 4) + SetDrawColor(1, 1, 1) + DrawImage(nil, ox + 4, oy + 4, w - 8, h - 8) + DrawString(0, oy + 10, "CENTER", 20, "VAR", txt) +end + +function copyTable(tbl) + local out = {} + for k, v in pairs(tbl) do + if type(v) == "table" then + out[k] = copyTable(v) + else + out[k] = v + end + end + return out +end + +function wipeTable(tbl) + if not tbl then + return { } + end + for k in pairs(tbl) do + tbl[k] = nil + end + return tbl +end + +function isValueInTable(tbl, val) + for k, v in pairs(tbl) do + if val == v then + return k + end + end +end + +function isValueInArray(tbl, val) + for i, v in ipairs(tbl) do + if val == v then + return i + end + end +end diff --git a/Data.lua b/Data.lua new file mode 100644 index 00000000..d3762bd3 --- /dev/null +++ b/Data.lua @@ -0,0 +1,94 @@ + +data = { } + +data.gems = { } +data.gems["_default"] = { + attack = true, + melee = true, + base = { + }, + quality = { + }, + levels = { + [1] = { } + }, +} +LoadModule("Gems/act_str", data.gems) +LoadModule("Gems/act_dex", data.gems) +LoadModule("Gems/act_int", data.gems) +LoadModule("Gems/sup_str", data.gems) +LoadModule("Gems/sup_dex", data.gems) +LoadModule("Gems/sup_int", data.gems) + +data.colorCodes = { + NORMAL = "^xC8C8C8", + MAGIC = "^x8888FF", + RARE = "^xFFFF77", + UNIQUE = "^xAF6025", + FIRE = "^x960000", + COLD = "^x366492", + LIGHT = "^xFFD700", + CHAOS = "^xD02090", +} + +data.jewelRadius = { + { rad = 800, col = "^xFFBB33", label = "Small" }, + { rad = 1200, col = "^x33FF66", label = "Medium" }, + { rad = 1500, col = "^x3333FF", label = "Large" } +} + +data.evasionTable = { 36, 42, 49, 56, 64, 72, 80, 89, 98, 108, + 118, 128, 140, 151, 164, 177, 190, 204, 219, 235, + 251, 268, 286, 305, 325, 345, 367, 389, 412, 437, + 463, 489, 517, 546, 577, 609, 642, 676, 713, 750, + 790, 831, 873, 918, 964, 1013, 1063, 1116, 1170, 1227, + 1287, 1349, 1413, 1480, 1550, 1623, 1698, 1777, 1859, 1944, + 2033, 2125, 2221, 2321, 2425, 2533, 2645, 2761, 2883, 3009, + 3140, 3276, 3418, 3565, 3717, 3876, 4041, 4213, 4391, 4574, + 4767, 4969, 5179, 5398 } + +data.weaponTypeInfo = { + ["None"] = { oneHand = true, melee = true, space = "unarmed" }, + ["Bow"] = { oneHand = false, melee = false, space = "bow" }, + ["Claw"] = { oneHand = true, melee = true, space = "claw" }, + ["Dagger"] = { oneHand = true, melee = true, space = "dagger" }, + ["Staff"] = { oneHand = false, melee = true, space = "staff" }, + ["Wand"] = { oneHand = true, melee = false, space = "wand" }, + ["One Handed Axe"] = { oneHand = true, melee = true, space = "axe" }, + ["One Handed Mace"] = { oneHand = true, melee = true, space = "mace" }, + ["One Handed Sword"] = { oneHand = true, melee = true, space = "sword" }, + ["Two Handed Axe"] = { oneHand = false, melee = true, space = "axe" }, + ["Two Handed Mace"] = { oneHand = false, melee = true, space = "mace" }, + ["Two Handed Sword"] = { oneHand = false, melee = true, space = "sword" }, +} + +data.unarmedWeap = { + [0] = { attackRate = 1.2, critChanceBase = 0, physicalMin = 2, physicalMax = 6 }, -- Scion + [1] = { attackRate = 1.2, critChanceBase = 0, physicalMin = 2, physicalMax = 8 }, -- Marauder + [2] = { attackRate = 1.2, critChanceBase = 0, physicalMin = 2, physicalMax = 5 }, -- Ranger + [3] = { attackRate = 1.2, critChanceBase = 0, physicalMin = 2, physicalMax = 5 }, -- Witch + [4] = { attackRate = 1.2, critChanceBase = 0, physicalMin = 2, physicalMax = 6 }, -- Duelist + [5] = { attackRate = 1.2, critChanceBase = 0, physicalMin = 2, physicalMax = 6 }, -- Templar + [6] = { attackRate = 1.2, critChanceBase = 0, physicalMin = 2, physicalMax = 5 }, -- Shadow +} + +data.itemBases = { } +local itemTypes = { + "axe", + "bow", + "claw", + "dagger", + "mace", + "staff", + "sword", + "wand", + "helm", + "body", + "glove", + "boots", + "shield", + "misc" +} +for _, type in pairs(itemTypes) do + LoadModule("items/"..type, data.itemBases) +end \ No newline at end of file diff --git a/Gems/SourceStat3.lnk b/Gems/SourceStat3.lnk new file mode 100644 index 00000000..642c7bd3 Binary files /dev/null and b/Gems/SourceStat3.lnk differ diff --git a/Gems/act_dex.lua b/Gems/act_dex.lua new file mode 100644 index 00000000..25e2c33b --- /dev/null +++ b/Gems/act_dex.lua @@ -0,0 +1,1823 @@ +local gems = ... + +gems["Animate Weapon"] = { + unsupported = true, +} +gems["Arctic Armor"] = { + unsupported = true, +} +gems["Barrage"] = { + attack = true, + bow = true, + projectile = true, + base = { + }, + quality = { + projectile_damageInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 7, attack_damageMore = 0.5, }, + [2] = { skill_manaCostBase = 7, attack_damageMore = 0.506, }, + [3] = { skill_manaCostBase = 7, attack_damageMore = 0.512, }, + [4] = { skill_manaCostBase = 8, attack_damageMore = 0.518, }, + [5] = { skill_manaCostBase = 8, attack_damageMore = 0.524, }, + [6] = { skill_manaCostBase = 8, attack_damageMore = 0.53, }, + [7] = { skill_manaCostBase = 8, attack_damageMore = 0.536, }, + [8] = { skill_manaCostBase = 8, attack_damageMore = 0.542, }, + [9] = { skill_manaCostBase = 9, attack_damageMore = 0.548, }, + [10] = { skill_manaCostBase = 9, attack_damageMore = 0.554, }, + [11] = { skill_manaCostBase = 9, attack_damageMore = 0.56, }, + [12] = { skill_manaCostBase = 9, attack_damageMore = 0.566, }, + [13] = { skill_manaCostBase = 9, attack_damageMore = 0.572, }, + [14] = { skill_manaCostBase = 10, attack_damageMore = 0.578, }, + [15] = { skill_manaCostBase = 10, attack_damageMore = 0.584, }, + [16] = { skill_manaCostBase = 10, attack_damageMore = 0.59, }, + [17] = { skill_manaCostBase = 10, attack_damageMore = 0.596, }, + [18] = { skill_manaCostBase = 10, attack_damageMore = 0.602, }, + [19] = { skill_manaCostBase = 11, attack_damageMore = 0.608, }, + [20] = { skill_manaCostBase = 11, attack_damageMore = 0.614, }, + [21] = { skill_manaCostBase = 11, attack_damageMore = 0.62, }, + [22] = { skill_manaCostBase = 11, attack_damageMore = 0.626, }, + [23] = { skill_manaCostBase = 11, attack_damageMore = 0.632, }, + [24] = { skill_manaCostBase = 11, attack_damageMore = 0.638, }, + [25] = { skill_manaCostBase = 11, attack_damageMore = 0.644, }, + [26] = { skill_manaCostBase = 12, attack_damageMore = 0.65, }, + [27] = { skill_manaCostBase = 12, attack_damageMore = 0.656, }, + [28] = { skill_manaCostBase = 12, attack_damageMore = 0.662, }, + [29] = { skill_manaCostBase = 12, attack_damageMore = 0.668, }, + [30] = { skill_manaCostBase = 12, attack_damageMore = 0.674, }, + } +} +gems["Bear Trap"] = { + cast = true, + trap = true, + base = { + skill_castTime = 1, + skill_damageEff = 2, + skill_critChanceBase = 5, + }, + quality = { + physicalInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 11, skill_physicalMin = 16, skill_physicalMax = 22, }, + [2] = { skill_manaCostBase = 13, skill_physicalMin = 20, skill_physicalMax = 28, }, + [3] = { skill_manaCostBase = 15, skill_physicalMin = 27, skill_physicalMax = 38, }, + [4] = { skill_manaCostBase = 17, skill_physicalMin = 35, skill_physicalMax = 49, }, + [5] = { skill_manaCostBase = 20, skill_physicalMin = 49, skill_physicalMax = 69, }, + [6] = { skill_manaCostBase = 22, skill_physicalMin = 67, skill_physicalMax = 94, }, + [7] = { skill_manaCostBase = 24, skill_physicalMin = 90, skill_physicalMax = 126, }, + [8] = { skill_manaCostBase = 26, skill_physicalMin = 119, skill_physicalMax = 167, }, + [9] = { skill_manaCostBase = 28, skill_physicalMin = 156, skill_physicalMax = 218, }, + [10] = { skill_manaCostBase = 32, skill_physicalMin = 202, skill_physicalMax = 282, }, + [11] = { skill_manaCostBase = 35, skill_physicalMin = 259, skill_physicalMax = 363, }, + [12] = { skill_manaCostBase = 38, skill_physicalMin = 331, skill_physicalMax = 463, }, + [13] = { skill_manaCostBase = 39, skill_physicalMin = 420, skill_physicalMax = 587, }, + [14] = { skill_manaCostBase = 41, skill_physicalMin = 530, skill_physicalMax = 742, }, + [15] = { skill_manaCostBase = 42, skill_physicalMin = 630, skill_physicalMax = 881, }, + [16] = { skill_manaCostBase = 43, skill_physicalMin = 746, skill_physicalMax = 1045, }, + [17] = { skill_manaCostBase = 44, skill_physicalMin = 883, skill_physicalMax = 1236, }, + [18] = { skill_manaCostBase = 45, skill_physicalMin = 1043, skill_physicalMax = 1460, }, + [19] = { skill_manaCostBase = 46, skill_physicalMin = 1230, skill_physicalMax = 1721, }, + [20] = { skill_manaCostBase = 46, skill_physicalMin = 1447, skill_physicalMax = 2026, }, + [21] = { skill_manaCostBase = 47, skill_physicalMin = 1613, skill_physicalMax = 2258, }, + [22] = { skill_manaCostBase = 48, skill_physicalMin = 1795, skill_physicalMax = 2514, }, + [23] = { skill_manaCostBase = 49, skill_physicalMin = 1998, skill_physicalMax = 2797, }, + [24] = { skill_manaCostBase = 50, skill_physicalMin = 2222, skill_physicalMax = 3111, }, + [25] = { skill_manaCostBase = 50, skill_physicalMin = 2470, skill_physicalMax = 3458, }, + [26] = { skill_manaCostBase = 51, skill_physicalMin = 2744, skill_physicalMax = 3842, }, + [27] = { skill_manaCostBase = 52, skill_physicalMin = 3047, skill_physicalMax = 4266, }, + [28] = { skill_manaCostBase = 53, skill_physicalMin = 3382, skill_physicalMax = 4735, }, + [29] = { skill_manaCostBase = 54, skill_physicalMin = 3753, skill_physicalMax = 5254, }, + [30] = { skill_manaCostBase = 54, skill_physicalMin = 4162, skill_physicalMax = 5826, }, + } +} +gems["Blade Vortex"] = { + spell = true, + aoe = true, + duration = true, + showAverage = true, + base = { + skill_castTime = 0.5, + skill_damageEff = 0.3, + skill_critChanceBase = 6, + skill_durationBase = 5, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 6, skill_physicalMin = 9, skill_physicalMax = 14, }, + [2] = { skill_manaCostBase = 7, skill_physicalMin = 11, skill_physicalMax = 17, }, + [3] = { skill_manaCostBase = 8, skill_physicalMin = 14, skill_physicalMax = 21, }, + [4] = { skill_manaCostBase = 9, skill_physicalMin = 18, skill_physicalMax = 26, }, + [5] = { skill_manaCostBase = 10, skill_physicalMin = 21, skill_physicalMax = 32, }, + [6] = { skill_manaCostBase = 11, skill_physicalMin = 26, skill_physicalMax = 38, }, + [7] = { skill_manaCostBase = 12, skill_physicalMin = 30, skill_physicalMax = 46, }, + [8] = { skill_manaCostBase = 13, skill_physicalMin = 34, skill_physicalMax = 52, }, + [9] = { skill_manaCostBase = 13, skill_physicalMin = 39, skill_physicalMax = 58, }, + [10] = { skill_manaCostBase = 14, skill_physicalMin = 44, skill_physicalMax = 65, }, + [11] = { skill_manaCostBase = 14, skill_physicalMin = 49, skill_physicalMax = 73, }, + [12] = { skill_manaCostBase = 15, skill_physicalMin = 55, skill_physicalMax = 82, }, + [13] = { skill_manaCostBase = 16, skill_physicalMin = 61, skill_physicalMax = 91, }, + [14] = { skill_manaCostBase = 16, skill_physicalMin = 68, skill_physicalMax = 101, }, + [15] = { skill_manaCostBase = 17, skill_physicalMin = 75, skill_physicalMax = 113, }, + [16] = { skill_manaCostBase = 18, skill_physicalMin = 83, skill_physicalMax = 125, }, + [17] = { skill_manaCostBase = 18, skill_physicalMin = 89, skill_physicalMax = 133, }, + [18] = { skill_manaCostBase = 19, skill_physicalMin = 95, skill_physicalMax = 142, }, + [19] = { skill_manaCostBase = 19, skill_physicalMin = 101, skill_physicalMax = 152, }, + [20] = { skill_manaCostBase = 19, skill_physicalMin = 108, skill_physicalMax = 162, }, + [21] = { skill_manaCostBase = 20, skill_physicalMin = 115, skill_physicalMax = 173, }, + [22] = { skill_manaCostBase = 21, skill_physicalMin = 123, skill_physicalMax = 184, }, + [23] = { skill_manaCostBase = 21, skill_physicalMin = 131, skill_physicalMax = 197, }, + [24] = { skill_manaCostBase = 21, skill_physicalMin = 139, skill_physicalMax = 209, }, + [25] = { skill_manaCostBase = 22, skill_physicalMin = 148, skill_physicalMax = 223, }, + [26] = { skill_manaCostBase = 23, skill_physicalMin = 158, skill_physicalMax = 237, }, + [27] = { skill_manaCostBase = 23, skill_physicalMin = 168, skill_physicalMax = 252, }, + [28] = { skill_manaCostBase = 23, skill_physicalMin = 178, skill_physicalMax = 267, }, + [29] = { skill_manaCostBase = 24, skill_physicalMin = 189, skill_physicalMax = 284, }, + [30] = { skill_manaCostBase = 24, skill_physicalMin = 201, skill_physicalMax = 302, }, + } +} +gems["Bladefall"] = { + spell = true, + aoe = true, + base = { + skill_castTime = 0.8, + skill_damageEff = 0.9, + skill_critChanceBase = 5, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 13, skill_physicalMin = 44, skill_physicalMax = 65, }, + [2] = { skill_manaCostBase = 14, skill_physicalMin = 52, skill_physicalMax = 78, }, + [3] = { skill_manaCostBase = 15, skill_physicalMin = 62, skill_physicalMax = 93, }, + [4] = { skill_manaCostBase = 16, skill_physicalMin = 73, skill_physicalMax = 110, }, + [5] = { skill_manaCostBase = 17, skill_physicalMin = 86, skill_physicalMax = 129, }, + [6] = { skill_manaCostBase = 18, skill_physicalMin = 96, skill_physicalMax = 144, }, + [7] = { skill_manaCostBase = 18, skill_physicalMin = 107, skill_physicalMax = 160, }, + [8] = { skill_manaCostBase = 19, skill_physicalMin = 118, skill_physicalMax = 177, }, + [9] = { skill_manaCostBase = 19, skill_physicalMin = 131, skill_physicalMax = 197, }, + [10] = { skill_manaCostBase = 20, skill_physicalMin = 145, skill_physicalMax = 218, }, + [11] = { skill_manaCostBase = 21, skill_physicalMin = 160, skill_physicalMax = 241, }, + [12] = { skill_manaCostBase = 21, skill_physicalMin = 177, skill_physicalMax = 266, }, + [13] = { skill_manaCostBase = 22, skill_physicalMin = 195, skill_physicalMax = 293, }, + [14] = { skill_manaCostBase = 22, skill_physicalMin = 215, skill_physicalMax = 323, }, + [15] = { skill_manaCostBase = 23, skill_physicalMin = 237, skill_physicalMax = 356, }, + [16] = { skill_manaCostBase = 24, skill_physicalMin = 261, skill_physicalMax = 392, }, + [17] = { skill_manaCostBase = 24, skill_physicalMin = 287, skill_physicalMax = 431, }, + [18] = { skill_manaCostBase = 25, skill_physicalMin = 315, skill_physicalMax = 473, }, + [19] = { skill_manaCostBase = 25, skill_physicalMin = 346, skill_physicalMax = 519, }, + [20] = { skill_manaCostBase = 26, skill_physicalMin = 380, skill_physicalMax = 570, }, + [21] = { skill_manaCostBase = 27, skill_physicalMin = 417, skill_physicalMax = 625, }, + [22] = { skill_manaCostBase = 27, skill_physicalMin = 457, skill_physicalMax = 685, }, + [23] = { skill_manaCostBase = 28, skill_physicalMin = 500, skill_physicalMax = 750, }, + [24] = { skill_manaCostBase = 28, skill_physicalMin = 548, skill_physicalMax = 821, }, + [25] = { skill_manaCostBase = 29, skill_physicalMin = 599, skill_physicalMax = 899, }, + [26] = { skill_manaCostBase = 30, skill_physicalMin = 655, skill_physicalMax = 983, }, + [27] = { skill_manaCostBase = 30, skill_physicalMin = 716, skill_physicalMax = 1074, }, + [28] = { skill_manaCostBase = 31, skill_physicalMin = 782, skill_physicalMax = 1174, }, + [29] = { skill_manaCostBase = 31, skill_physicalMin = 854, skill_physicalMax = 1282, }, + [30] = { skill_manaCostBase = 32, skill_physicalMin = 933, skill_physicalMax = 1399, }, + } +} +gems["Blast Rain"] = { + attack = true, + bow = true, + projectile = true, + aoe = true, + fire = true, + base = { + physicalConvertTofire = 50, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 8, attack_damageMore = 0.4, }, + [2] = { skill_manaCostBase = 8, attack_damageMore = 0.404, }, + [3] = { skill_manaCostBase = 8, attack_damageMore = 0.408, }, + [4] = { skill_manaCostBase = 8, attack_damageMore = 0.412, }, + [5] = { skill_manaCostBase = 9, attack_damageMore = 0.416, }, + [6] = { skill_manaCostBase = 9, attack_damageMore = 0.42, }, + [7] = { skill_manaCostBase = 9, attack_damageMore = 0.424, }, + [8] = { skill_manaCostBase = 9, attack_damageMore = 0.428, }, + [9] = { skill_manaCostBase = 9, attack_damageMore = 0.432, }, + [10] = { skill_manaCostBase = 9, attack_damageMore = 0.436, }, + [11] = { skill_manaCostBase = 9, attack_damageMore = 0.44, }, + [12] = { skill_manaCostBase = 10, attack_damageMore = 0.444, }, + [13] = { skill_manaCostBase = 10, attack_damageMore = 0.448, }, + [14] = { skill_manaCostBase = 10, attack_damageMore = 0.452, }, + [15] = { skill_manaCostBase = 10, attack_damageMore = 0.456, }, + [16] = { skill_manaCostBase = 10, attack_damageMore = 0.46, }, + [17] = { skill_manaCostBase = 10, attack_damageMore = 0.464, }, + [18] = { skill_manaCostBase = 10, attack_damageMore = 0.468, }, + [19] = { skill_manaCostBase = 10, attack_damageMore = 0.472, }, + [20] = { skill_manaCostBase = 10, attack_damageMore = 0.476, }, + [21] = { skill_manaCostBase = 10, attack_damageMore = 0.48, }, + [22] = { skill_manaCostBase = 10, attack_damageMore = 0.484, }, + [23] = { skill_manaCostBase = 11, attack_damageMore = 0.488, }, + [24] = { skill_manaCostBase = 11, attack_damageMore = 0.492, }, + [25] = { skill_manaCostBase = 11, attack_damageMore = 0.496, }, + [26] = { skill_manaCostBase = 11, attack_damageMore = 0.5, }, + [27] = { skill_manaCostBase = 11, attack_damageMore = 0.504, }, + [28] = { skill_manaCostBase = 12, attack_damageMore = 0.508, }, + [29] = { skill_manaCostBase = 12, attack_damageMore = 0.512, }, + [30] = { skill_manaCostBase = 12, attack_damageMore = 0.516, }, + } +} +gems["Blink Arrow"] = { + unsupported = true, +} +gems["Blood Rage"] = { + spell = true, + duration = true, + base = { + }, + quality = { + buff_attackSpeedInc = 0.25, + }, + levels = { + [1] = { skill_manaCostBase = 17, skill_durationBase = 7, buff_attackSpeedInc = 5, }, + [2] = { skill_manaCostBase = 17, skill_durationBase = 7.2, buff_attackSpeedInc = 6, }, + [3] = { skill_manaCostBase = 17, skill_durationBase = 7.4, buff_attackSpeedInc = 6, }, + [4] = { skill_manaCostBase = 18, skill_durationBase = 7.6, buff_attackSpeedInc = 7, }, + [5] = { skill_manaCostBase = 18, skill_durationBase = 7.8, buff_attackSpeedInc = 7, }, + [6] = { skill_manaCostBase = 18, skill_durationBase = 8, buff_attackSpeedInc = 8, }, + [7] = { skill_manaCostBase = 18, skill_durationBase = 8.2, buff_attackSpeedInc = 8, }, + [8] = { skill_manaCostBase = 19, skill_durationBase = 8.4, buff_attackSpeedInc = 9, }, + [9] = { skill_manaCostBase = 19, skill_durationBase = 8.6, buff_attackSpeedInc = 9, }, + [10] = { skill_manaCostBase = 19, skill_durationBase = 8.8, buff_attackSpeedInc = 10, }, + [11] = { skill_manaCostBase = 20, skill_durationBase = 9, buff_attackSpeedInc = 10, }, + [12] = { skill_manaCostBase = 20, skill_durationBase = 9.2, buff_attackSpeedInc = 11, }, + [13] = { skill_manaCostBase = 20, skill_durationBase = 9.4, buff_attackSpeedInc = 11, }, + [14] = { skill_manaCostBase = 20, skill_durationBase = 9.6, buff_attackSpeedInc = 12, }, + [15] = { skill_manaCostBase = 20, skill_durationBase = 9.8, buff_attackSpeedInc = 12, }, + [16] = { skill_manaCostBase = 21, skill_durationBase = 10, buff_attackSpeedInc = 13, }, + [17] = { skill_manaCostBase = 21, skill_durationBase = 10.2, buff_attackSpeedInc = 13, }, + [18] = { skill_manaCostBase = 21, skill_durationBase = 10.4, buff_attackSpeedInc = 14, }, + [19] = { skill_manaCostBase = 21, skill_durationBase = 10.6, buff_attackSpeedInc = 14, }, + [20] = { skill_manaCostBase = 21, skill_durationBase = 10.8, buff_attackSpeedInc = 15, }, + [21] = { skill_manaCostBase = 22, skill_durationBase = 11, buff_attackSpeedInc = 15, }, + [22] = { skill_manaCostBase = 22, skill_durationBase = 11.2, buff_attackSpeedInc = 16, }, + [23] = { skill_manaCostBase = 22, skill_durationBase = 11.4, buff_attackSpeedInc = 16, }, + [24] = { skill_manaCostBase = 22, skill_durationBase = 11.6, buff_attackSpeedInc = 17, }, + [25] = { skill_manaCostBase = 22, skill_durationBase = 11.8, buff_attackSpeedInc = 17, }, + [26] = { skill_manaCostBase = 23, skill_durationBase = 12, buff_attackSpeedInc = 18, }, + [27] = { skill_manaCostBase = 23, skill_durationBase = 12.2, buff_attackSpeedInc = 18, }, + [28] = { skill_manaCostBase = 23, skill_durationBase = 12.4, buff_attackSpeedInc = 19, }, + [29] = { skill_manaCostBase = 23, skill_durationBase = 12.6, buff_attackSpeedInc = 19, }, + [30] = { skill_manaCostBase = 23, skill_durationBase = 12.8, buff_attackSpeedInc = 20, }, + } +} +gems["Burning Arrow"] = { + attack = true, + bow = true, + projectile = true, + fire = true, + base = { + physicalConvertTofire = 50, + igniteChance = 20, + }, + quality = { + ignite_durationInc = 3, + }, + levels = { + [1] = { skill_manaCostBase = 5, attack_damageMore = 1.5, degen_fireInc = 10, }, + [2] = { skill_manaCostBase = 5, attack_damageMore = 1.518, degen_fireInc = 11, }, + [3] = { skill_manaCostBase = 5, attack_damageMore = 1.536, degen_fireInc = 12, }, + [4] = { skill_manaCostBase = 5, attack_damageMore = 1.554, degen_fireInc = 13, }, + [5] = { skill_manaCostBase = 5, attack_damageMore = 1.572, degen_fireInc = 14, }, + [6] = { skill_manaCostBase = 6, attack_damageMore = 1.59, degen_fireInc = 15, }, + [7] = { skill_manaCostBase = 6, attack_damageMore = 1.608, degen_fireInc = 16, }, + [8] = { skill_manaCostBase = 6, attack_damageMore = 1.626, degen_fireInc = 17, }, + [9] = { skill_manaCostBase = 6, attack_damageMore = 1.644, degen_fireInc = 18, }, + [10] = { skill_manaCostBase = 6, attack_damageMore = 1.662, degen_fireInc = 19, }, + [11] = { skill_manaCostBase = 7, attack_damageMore = 1.68, degen_fireInc = 20, }, + [12] = { skill_manaCostBase = 7, attack_damageMore = 1.698, degen_fireInc = 21, }, + [13] = { skill_manaCostBase = 7, attack_damageMore = 1.716, degen_fireInc = 22, }, + [14] = { skill_manaCostBase = 7, attack_damageMore = 1.734, degen_fireInc = 23, }, + [15] = { skill_manaCostBase = 7, attack_damageMore = 1.752, degen_fireInc = 24, }, + [16] = { skill_manaCostBase = 8, attack_damageMore = 1.77, degen_fireInc = 25, }, + [17] = { skill_manaCostBase = 8, attack_damageMore = 1.788, degen_fireInc = 26, }, + [18] = { skill_manaCostBase = 8, attack_damageMore = 1.806, degen_fireInc = 27, }, + [19] = { skill_manaCostBase = 8, attack_damageMore = 1.824, degen_fireInc = 28, }, + [20] = { skill_manaCostBase = 8, attack_damageMore = 1.842, degen_fireInc = 29, }, + [21] = { skill_manaCostBase = 9, attack_damageMore = 1.86, degen_fireInc = 30, }, + [22] = { skill_manaCostBase = 9, attack_damageMore = 1.878, degen_fireInc = 31, }, + [23] = { skill_manaCostBase = 9, attack_damageMore = 1.896, degen_fireInc = 32, }, + [24] = { skill_manaCostBase = 9, attack_damageMore = 1.914, degen_fireInc = 33, }, + [25] = { skill_manaCostBase = 9, attack_damageMore = 1.932, degen_fireInc = 34, }, + [26] = { skill_manaCostBase = 10, attack_damageMore = 1.95, degen_fireInc = 35, }, + [27] = { skill_manaCostBase = 10, attack_damageMore = 1.968, degen_fireInc = 36, }, + [28] = { skill_manaCostBase = 10, attack_damageMore = 1.986, degen_fireInc = 37, }, + [29] = { skill_manaCostBase = 10, attack_damageMore = 2.004, degen_fireInc = 38, }, + [30] = { skill_manaCostBase = 10, attack_damageMore = 2.022, degen_fireInc = 39, }, + } +} +gems["Caustic Arrow"] = { + attack = true, + bow = true, + projectile = true, + aoe = true, + duration = true, + chaos = true, + base = { + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 8, skill_durationBase = 2.8, skill_chaosDotBase = 5.2, physicalGainAschaos = 30, }, + [2] = { skill_manaCostBase = 8, skill_durationBase = 2.9, skill_chaosDotBase = 6.5, physicalGainAschaos = 31, }, + [3] = { skill_manaCostBase = 8, skill_durationBase = 3, skill_chaosDotBase = 8.8, physicalGainAschaos = 32, }, + [4] = { skill_manaCostBase = 9, skill_durationBase = 3.1, skill_chaosDotBase = 11.7, physicalGainAschaos = 33, }, + [5] = { skill_manaCostBase = 9, skill_durationBase = 3.2, skill_chaosDotBase = 16.5, physicalGainAschaos = 34, }, + [6] = { skill_manaCostBase = 9, skill_durationBase = 3.3, skill_chaosDotBase = 22.8, physicalGainAschaos = 35, }, + [7] = { skill_manaCostBase = 10, skill_durationBase = 3.4, skill_chaosDotBase = 30.8, physicalGainAschaos = 36, }, + [8] = { skill_manaCostBase = 10, skill_durationBase = 3.5, skill_chaosDotBase = 41, physicalGainAschaos = 37, }, + [9] = { skill_manaCostBase = 10, skill_durationBase = 3.6, skill_chaosDotBase = 54.1, physicalGainAschaos = 38, }, + [10] = { skill_manaCostBase = 11, skill_durationBase = 3.7, skill_chaosDotBase = 70.7, physicalGainAschaos = 39, }, + [11] = { skill_manaCostBase = 11, skill_durationBase = 3.9, skill_chaosDotBase = 91.7, physicalGainAschaos = 40, }, + [12] = { skill_manaCostBase = 12, skill_durationBase = 4, skill_chaosDotBase = 118.1, physicalGainAschaos = 41, }, + [13] = { skill_manaCostBase = 12, skill_durationBase = 4.1, skill_chaosDotBase = 151.3, physicalGainAschaos = 42, }, + [14] = { skill_manaCostBase = 13, skill_durationBase = 4.2, skill_chaosDotBase = 193, physicalGainAschaos = 43, }, + [15] = { skill_manaCostBase = 13, skill_durationBase = 4.3, skill_chaosDotBase = 230.9, physicalGainAschaos = 44, }, + [16] = { skill_manaCostBase = 14, skill_durationBase = 4.4, skill_chaosDotBase = 275.7, physicalGainAschaos = 45, }, + [17] = { skill_manaCostBase = 14, skill_durationBase = 4.5, skill_chaosDotBase = 328.6, physicalGainAschaos = 46, }, + [18] = { skill_manaCostBase = 15, skill_durationBase = 4.6, skill_chaosDotBase = 390.8, physicalGainAschaos = 47, }, + [19] = { skill_manaCostBase = 15, skill_durationBase = 4.7, skill_chaosDotBase = 464.1, physicalGainAschaos = 48, }, + [20] = { skill_manaCostBase = 16, skill_durationBase = 4.8, skill_chaosDotBase = 550.3, physicalGainAschaos = 49, }, + [21] = { skill_manaCostBase = 16, skill_durationBase = 5, skill_chaosDotBase = 616, physicalGainAschaos = 50, }, + [22] = { skill_manaCostBase = 17, skill_durationBase = 5.1, skill_chaosDotBase = 689.2, physicalGainAschaos = 51, }, + [23] = { skill_manaCostBase = 17, skill_durationBase = 5.2, skill_chaosDotBase = 770.6, physicalGainAschaos = 52, }, + [24] = { skill_manaCostBase = 18, skill_durationBase = 5.3, skill_chaosDotBase = 861.1, physicalGainAschaos = 53, }, + [25] = { skill_manaCostBase = 18, skill_durationBase = 5.4, skill_chaosDotBase = 961.8, physicalGainAschaos = 54, }, + [26] = { skill_manaCostBase = 19, skill_durationBase = 5.5, skill_chaosDotBase = 1073.7, physicalGainAschaos = 55, }, + [27] = { skill_manaCostBase = 19, skill_durationBase = 5.6, skill_chaosDotBase = 1198, physicalGainAschaos = 56, }, + [28] = { skill_manaCostBase = 20, skill_durationBase = 5.7, skill_chaosDotBase = 1336.2, physicalGainAschaos = 57, }, + [29] = { skill_manaCostBase = 20, skill_durationBase = 5.8, skill_chaosDotBase = 1489.6, physicalGainAschaos = 58, }, + [30] = { skill_manaCostBase = 21, skill_durationBase = 5.9, skill_chaosDotBase = 1660, physicalGainAschaos = 59, }, + } +} +gems["Cyclone"] = { + attack = true, + melee = true, + aoe = true, + movement = true, + base = { + skill_manaCostBase = 12, + attackSpeedMore = 1.5, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { attack_damageMore = 0.45, }, + [2] = { attack_damageMore = 0.456, }, + [3] = { attack_damageMore = 0.462, }, + [4] = { attack_damageMore = 0.468, }, + [5] = { attack_damageMore = 0.474, }, + [6] = { attack_damageMore = 0.48, }, + [7] = { attack_damageMore = 0.486, }, + [8] = { attack_damageMore = 0.492, }, + [9] = { attack_damageMore = 0.498, }, + [10] = { attack_damageMore = 0.504, }, + [11] = { attack_damageMore = 0.51, }, + [12] = { attack_damageMore = 0.516, }, + [13] = { attack_damageMore = 0.522, }, + [14] = { attack_damageMore = 0.528, }, + [15] = { attack_damageMore = 0.534, }, + [16] = { attack_damageMore = 0.54, }, + [17] = { attack_damageMore = 0.546, }, + [18] = { attack_damageMore = 0.552, }, + [19] = { attack_damageMore = 0.558, }, + [20] = { attack_damageMore = 0.564, }, + [21] = { attack_damageMore = 0.57, }, + [22] = { attack_damageMore = 0.576, }, + [23] = { attack_damageMore = 0.582, }, + [24] = { attack_damageMore = 0.588, }, + [25] = { attack_damageMore = 0.594, }, + [26] = { attack_damageMore = 0.6, }, + [27] = { attack_damageMore = 0.606, }, + [28] = { attack_damageMore = 0.612, }, + [29] = { attack_damageMore = 0.618, }, + [30] = { attack_damageMore = 0.624, }, + } +} +gems["Desecrate"] = { + unsupported = true, +} +gems["Detonate Dead"] = { + unsupported = true, +} +gems["Double Strike"] = { + attack = true, + melee = true, + base = { + skill_manaCostBase = 5, + }, + quality = { + attackSpeedInc = 0.5, + }, + levels = { + [1] = { attack_damageMore = 0.7, }, + [2] = { attack_damageMore = 0.708, }, + [3] = { attack_damageMore = 0.716, }, + [4] = { attack_damageMore = 0.724, }, + [5] = { attack_damageMore = 0.732, }, + [6] = { attack_damageMore = 0.74, }, + [7] = { attack_damageMore = 0.748, }, + [8] = { attack_damageMore = 0.756, }, + [9] = { attack_damageMore = 0.764, }, + [10] = { attack_damageMore = 0.772, }, + [11] = { attack_damageMore = 0.78, }, + [12] = { attack_damageMore = 0.788, }, + [13] = { attack_damageMore = 0.796, }, + [14] = { attack_damageMore = 0.804, }, + [15] = { attack_damageMore = 0.812, }, + [16] = { attack_damageMore = 0.82, }, + [17] = { attack_damageMore = 0.828, }, + [18] = { attack_damageMore = 0.836, }, + [19] = { attack_damageMore = 0.844, }, + [20] = { attack_damageMore = 0.852, }, + [21] = { attack_damageMore = 0.86, }, + [22] = { attack_damageMore = 0.868, }, + [23] = { attack_damageMore = 0.876, }, + [24] = { attack_damageMore = 0.884, }, + [25] = { attack_damageMore = 0.892, }, + [26] = { attack_damageMore = 0.9, }, + [27] = { attack_damageMore = 0.908, }, + [28] = { attack_damageMore = 0.916, }, + [29] = { attack_damageMore = 0.924, }, + [30] = { attack_damageMore = 0.932, }, + } +} +gems["Dual Strike"] = { + unsupported = true, +} +gems["Elemental Hit"] = { + attack = true, + melee = true, + bow = true, + projectile = true, + lightning = true, + cold = true, + fire = true, + parts = { + { + name = "Added fire", + }, + { + name = "Added cold", + }, + { + name = "Added lightning", + }, + }, + base = { + freezeChance = 10, + shockChance = 10, + igniteChance = 10, + }, + quality = { + elemInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 6, part1_attack_fireMin = 4, part1_attack_fireMax = 8, part2_attack_coldMin = 3, part2_attack_coldMax = 6, part3_attack_lightningMin = 1, part3_attack_lightningMax = 13, }, + [2] = { skill_manaCostBase = 6, part1_attack_fireMin = 5, part1_attack_fireMax = 9, part2_attack_coldMin = 4, part2_attack_coldMax = 7, part3_attack_lightningMin = 1, part3_attack_lightningMax = 14, }, + [3] = { skill_manaCostBase = 6, part1_attack_fireMin = 6, part1_attack_fireMax = 11, part2_attack_coldMin = 5, part2_attack_coldMax = 9, part3_attack_lightningMin = 1, part3_attack_lightningMax = 17, }, + [4] = { skill_manaCostBase = 7, part1_attack_fireMin = 7, part1_attack_fireMax = 14, part2_attack_coldMin = 6, part2_attack_coldMax = 11, part3_attack_lightningMin = 1, part3_attack_lightningMax = 23, }, + [5] = { skill_manaCostBase = 7, part1_attack_fireMin = 10, part1_attack_fireMax = 19, part2_attack_coldMin = 8, part2_attack_coldMax = 16, part3_attack_lightningMin = 2, part3_attack_lightningMax = 31, }, + [6] = { skill_manaCostBase = 7, part1_attack_fireMin = 14, part1_attack_fireMax = 27, part2_attack_coldMin = 12, part2_attack_coldMax = 22, part3_attack_lightningMin = 2, part3_attack_lightningMax = 44, }, + [7] = { skill_manaCostBase = 8, part1_attack_fireMin = 18, part1_attack_fireMax = 34, part2_attack_coldMin = 15, part2_attack_coldMax = 28, part3_attack_lightningMin = 3, part3_attack_lightningMax = 56, }, + [8] = { skill_manaCostBase = 8, part1_attack_fireMin = 23, part1_attack_fireMax = 43, part2_attack_coldMin = 19, part2_attack_coldMax = 35, part3_attack_lightningMin = 4, part3_attack_lightningMax = 70, }, + [9] = { skill_manaCostBase = 8, part1_attack_fireMin = 28, part1_attack_fireMax = 53, part2_attack_coldMin = 23, part2_attack_coldMax = 43, part3_attack_lightningMin = 5, part3_attack_lightningMax = 87, }, + [10] = { skill_manaCostBase = 9, part1_attack_fireMin = 35, part1_attack_fireMax = 64, part2_attack_coldMin = 28, part2_attack_coldMax = 53, part3_attack_lightningMin = 6, part3_attack_lightningMax = 106, }, + [11] = { skill_manaCostBase = 9, part1_attack_fireMin = 42, part1_attack_fireMax = 78, part2_attack_coldMin = 34, part2_attack_coldMax = 64, part3_attack_lightningMin = 7, part3_attack_lightningMax = 128, }, + [12] = { skill_manaCostBase = 9, part1_attack_fireMin = 50, part1_attack_fireMax = 93, part2_attack_coldMin = 41, part2_attack_coldMax = 76, part3_attack_lightningMin = 8, part3_attack_lightningMax = 153, }, + [13] = { skill_manaCostBase = 10, part1_attack_fireMin = 60, part1_attack_fireMax = 111, part2_attack_coldMin = 49, part2_attack_coldMax = 91, part3_attack_lightningMin = 10, part3_attack_lightningMax = 183, }, + [14] = { skill_manaCostBase = 10, part1_attack_fireMin = 71, part1_attack_fireMax = 132, part2_attack_coldMin = 58, part2_attack_coldMax = 108, part3_attack_lightningMin = 11, part3_attack_lightningMax = 217, }, + [15] = { skill_manaCostBase = 10, part1_attack_fireMin = 84, part1_attack_fireMax = 156, part2_attack_coldMin = 69, part2_attack_coldMax = 127, part3_attack_lightningMin = 13, part3_attack_lightningMax = 256, }, + [16] = { skill_manaCostBase = 11, part1_attack_fireMin = 99, part1_attack_fireMax = 183, part2_attack_coldMin = 81, part2_attack_coldMax = 150, part3_attack_lightningMin = 16, part3_attack_lightningMax = 301, }, + [17] = { skill_manaCostBase = 11, part1_attack_fireMin = 115, part1_attack_fireMax = 214, part2_attack_coldMin = 94, part2_attack_coldMax = 175, part3_attack_lightningMin = 19, part3_attack_lightningMax = 352, }, + [18] = { skill_manaCostBase = 11, part1_attack_fireMin = 135, part1_attack_fireMax = 250, part2_attack_coldMin = 110, part2_attack_coldMax = 205, part3_attack_lightningMin = 22, part3_attack_lightningMax = 411, }, + [19] = { skill_manaCostBase = 11, part1_attack_fireMin = 151, part1_attack_fireMax = 280, part2_attack_coldMin = 123, part2_attack_coldMax = 229, part3_attack_lightningMin = 24, part3_attack_lightningMax = 461, }, + [20] = { skill_manaCostBase = 12, part1_attack_fireMin = 169, part1_attack_fireMax = 314, part2_attack_coldMin = 138, part2_attack_coldMax = 257, part3_attack_lightningMin = 27, part3_attack_lightningMax = 516, }, + [21] = { skill_manaCostBase = 12, part1_attack_fireMin = 182, part1_attack_fireMax = 338, part2_attack_coldMin = 149, part2_attack_coldMax = 276, part3_attack_lightningMin = 29, part3_attack_lightningMax = 555, }, + [22] = { skill_manaCostBase = 12, part1_attack_fireMin = 196, part1_attack_fireMax = 364, part2_attack_coldMin = 160, part2_attack_coldMax = 297, part3_attack_lightningMin = 31, part3_attack_lightningMax = 598, }, + [23] = { skill_manaCostBase = 12, part1_attack_fireMin = 211, part1_attack_fireMax = 391, part2_attack_coldMin = 172, part2_attack_coldMax = 320, part3_attack_lightningMin = 34, part3_attack_lightningMax = 643, }, + [24] = { skill_manaCostBase = 13, part1_attack_fireMin = 226, part1_attack_fireMax = 420, part2_attack_coldMin = 185, part2_attack_coldMax = 344, part3_attack_lightningMin = 36, part3_attack_lightningMax = 691, }, + [25] = { skill_manaCostBase = 13, part1_attack_fireMin = 243, part1_attack_fireMax = 452, part2_attack_coldMin = 199, part2_attack_coldMax = 370, part3_attack_lightningMin = 39, part3_attack_lightningMax = 743, }, + [26] = { skill_manaCostBase = 13, part1_attack_fireMin = 261, part1_attack_fireMax = 485, part2_attack_coldMin = 214, part2_attack_coldMax = 397, part3_attack_lightningMin = 42, part3_attack_lightningMax = 798, }, + [27] = { skill_manaCostBase = 13, part1_attack_fireMin = 281, part1_attack_fireMax = 521, part2_attack_coldMin = 230, part2_attack_coldMax = 426, part3_attack_lightningMin = 45, part3_attack_lightningMax = 857, }, + [28] = { skill_manaCostBase = 14, part1_attack_fireMin = 301, part1_attack_fireMax = 559, part2_attack_coldMin = 246, part2_attack_coldMax = 457, part3_attack_lightningMin = 48, part3_attack_lightningMax = 919, }, + [29] = { skill_manaCostBase = 14, part1_attack_fireMin = 323, part1_attack_fireMax = 600, part2_attack_coldMin = 264, part2_attack_coldMax = 491, part3_attack_lightningMin = 52, part3_attack_lightningMax = 986, }, + [30] = { skill_manaCostBase = 14, part1_attack_fireMin = 346, part1_attack_fireMax = 643, part2_attack_coldMin = 283, part2_attack_coldMax = 526, part3_attack_lightningMin = 56, part3_attack_lightningMax = 1057, }, + } +} +gems["Ethereal Knives"] = { + spell = true, + projectile = true, + base = { + skill_castTime = 0.6, + skill_damageEff = 1, + skill_critChanceBase = 6, + }, + quality = { + projectileSpeedInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 5, skill_physicalMin = 4, skill_physicalMax = 6, projectileSpeedInc = 0, }, + [2] = { skill_manaCostBase = 6, skill_physicalMin = 5, skill_physicalMax = 7, projectileSpeedInc = 1, }, + [3] = { skill_manaCostBase = 7, skill_physicalMin = 6, skill_physicalMax = 9, projectileSpeedInc = 2, }, + [4] = { skill_manaCostBase = 8, skill_physicalMin = 8, skill_physicalMax = 12, projectileSpeedInc = 3, }, + [5] = { skill_manaCostBase = 9, skill_physicalMin = 12, skill_physicalMax = 18, projectileSpeedInc = 4, }, + [6] = { skill_manaCostBase = 10, skill_physicalMin = 18, skill_physicalMax = 27, projectileSpeedInc = 5, }, + [7] = { skill_manaCostBase = 11, skill_physicalMin = 24, skill_physicalMax = 37, projectileSpeedInc = 6, }, + [8] = { skill_manaCostBase = 12, skill_physicalMin = 32, skill_physicalMax = 49, projectileSpeedInc = 7, }, + [9] = { skill_manaCostBase = 13, skill_physicalMin = 42, skill_physicalMax = 64, projectileSpeedInc = 8, }, + [10] = { skill_manaCostBase = 14, skill_physicalMin = 55, skill_physicalMax = 82, projectileSpeedInc = 9, }, + [11] = { skill_manaCostBase = 16, skill_physicalMin = 70, skill_physicalMax = 105, projectileSpeedInc = 10, }, + [12] = { skill_manaCostBase = 17, skill_physicalMin = 89, skill_physicalMax = 134, projectileSpeedInc = 11, }, + [13] = { skill_manaCostBase = 18, skill_physicalMin = 112, skill_physicalMax = 169, projectileSpeedInc = 12, }, + [14] = { skill_manaCostBase = 18, skill_physicalMin = 141, skill_physicalMax = 212, projectileSpeedInc = 13, }, + [15] = { skill_manaCostBase = 19, skill_physicalMin = 176, skill_physicalMax = 265, projectileSpeedInc = 14, }, + [16] = { skill_manaCostBase = 20, skill_physicalMin = 219, skill_physicalMax = 329, projectileSpeedInc = 15, }, + [17] = { skill_manaCostBase = 21, skill_physicalMin = 272, skill_physicalMax = 408, projectileSpeedInc = 16, }, + [18] = { skill_manaCostBase = 22, skill_physicalMin = 336, skill_physicalMax = 504, projectileSpeedInc = 17, }, + [19] = { skill_manaCostBase = 22, skill_physicalMin = 393, skill_physicalMax = 590, projectileSpeedInc = 18, }, + [20] = { skill_manaCostBase = 23, skill_physicalMin = 459, skill_physicalMax = 688, projectileSpeedInc = 19, }, + [21] = { skill_manaCostBase = 24, skill_physicalMin = 509, skill_physicalMax = 763, projectileSpeedInc = 20, }, + [22] = { skill_manaCostBase = 24, skill_physicalMin = 563, skill_physicalMax = 845, projectileSpeedInc = 21, }, + [23] = { skill_manaCostBase = 25, skill_physicalMin = 623, skill_physicalMax = 935, projectileSpeedInc = 22, }, + [24] = { skill_manaCostBase = 25, skill_physicalMin = 690, skill_physicalMax = 1034, projectileSpeedInc = 23, }, + [25] = { skill_manaCostBase = 26, skill_physicalMin = 762, skill_physicalMax = 1144, projectileSpeedInc = 24, }, + [26] = { skill_manaCostBase = 26, skill_physicalMin = 842, skill_physicalMax = 1264, projectileSpeedInc = 25, }, + [27] = { skill_manaCostBase = 27, skill_physicalMin = 931, skill_physicalMax = 1396, projectileSpeedInc = 26, }, + [28] = { skill_manaCostBase = 27, skill_physicalMin = 1027, skill_physicalMax = 1541, projectileSpeedInc = 27, }, + [29] = { skill_manaCostBase = 28, skill_physicalMin = 1134, skill_physicalMax = 1701, projectileSpeedInc = 28, }, + [30] = { skill_manaCostBase = 29, skill_physicalMin = 1251, skill_physicalMax = 1876, projectileSpeedInc = 29, }, + } +} +gems["Explosive Arrow"] = { + attack = true, + bow = true, + projectile = true, + aoe = true, + duration = true, + fire = true, + parts = { + { + name = "Explosion", + attack = false, + cast = true, + }, + { + name = "Arrow", + attack = true, + cast = false, + }, + }, + base = { + skill_critChanceBase = 6, + skill_durationBase = 1, + attack_damageMore = 0, + }, + quality = { + igniteChance = 1, + }, + levels = { + [1] = { skill_manaCostBase = 18, skill_fireMin = 44, skill_fireMax = 66, }, + [2] = { skill_manaCostBase = 19, skill_fireMin = 54, skill_fireMax = 81, }, + [3] = { skill_manaCostBase = 20, skill_fireMin = 66, skill_fireMax = 99, }, + [4] = { skill_manaCostBase = 21, skill_fireMin = 80, skill_fireMax = 121, }, + [5] = { skill_manaCostBase = 21, skill_fireMin = 98, skill_fireMax = 146, }, + [6] = { skill_manaCostBase = 22, skill_fireMin = 111, skill_fireMax = 166, }, + [7] = { skill_manaCostBase = 22, skill_fireMin = 126, skill_fireMax = 189, }, + [8] = { skill_manaCostBase = 23, skill_fireMin = 142, skill_fireMax = 214, }, + [9] = { skill_manaCostBase = 23, skill_fireMin = 161, skill_fireMax = 242, }, + [10] = { skill_manaCostBase = 24, skill_fireMin = 182, skill_fireMax = 273, }, + [11] = { skill_manaCostBase = 24, skill_fireMin = 205, skill_fireMax = 308, }, + [12] = { skill_manaCostBase = 24, skill_fireMin = 232, skill_fireMax = 347, }, + [13] = { skill_manaCostBase = 26, skill_fireMin = 261, skill_fireMax = 391, }, + [14] = { skill_manaCostBase = 26, skill_fireMin = 293, skill_fireMax = 440, }, + [15] = { skill_manaCostBase = 26, skill_fireMin = 330, skill_fireMax = 495, }, + [16] = { skill_manaCostBase = 26, skill_fireMin = 371, skill_fireMax = 556, }, + [17] = { skill_manaCostBase = 26, skill_fireMin = 416, skill_fireMax = 624, }, + [18] = { skill_manaCostBase = 27, skill_fireMin = 467, skill_fireMax = 700, }, + [19] = { skill_manaCostBase = 27, skill_fireMin = 523, skill_fireMax = 785, }, + [20] = { skill_manaCostBase = 27, skill_fireMin = 586, skill_fireMax = 879, }, + [21] = { skill_manaCostBase = 28, skill_fireMin = 656, skill_fireMax = 984, }, + [22] = { skill_manaCostBase = 28, skill_fireMin = 734, skill_fireMax = 1100, }, + [23] = { skill_manaCostBase = 29, skill_fireMin = 820, skill_fireMax = 1230, }, + [24] = { skill_manaCostBase = 29, skill_fireMin = 917, skill_fireMax = 1375, }, + [25] = { skill_manaCostBase = 30, skill_fireMin = 1024, skill_fireMax = 1536, }, + [26] = { skill_manaCostBase = 30, skill_fireMin = 1143, skill_fireMax = 1714, }, + [27] = { skill_manaCostBase = 30, skill_fireMin = 1275, skill_fireMax = 1913, }, + [28] = { skill_manaCostBase = 30, skill_fireMin = 1422, skill_fireMax = 2134, }, + [29] = { skill_manaCostBase = 31, skill_fireMin = 1586, skill_fireMax = 2379, }, + [30] = { skill_manaCostBase = 31, skill_fireMin = 1767, skill_fireMax = 2651, }, + } +} +gems["Fire Trap"] = { + spell = true, + trap = true, + aoe = true, + duration = true, + fire = true, + base = { + skill_castTime = 1, + skill_damageEff = 1, + skill_critChanceBase = 6, + skill_durationBase = 8, + }, + quality = { + degen_fireInc = 1.5, + }, + levels = { + [1] = { skill_manaCostBase = 7, skill_fireMin = 2, skill_fireMax = 4, skill_fireDotBase = 3.6, }, + [2] = { skill_manaCostBase = 8, skill_fireMin = 3, skill_fireMax = 5, skill_fireDotBase = 4.1, }, + [3] = { skill_manaCostBase = 9, skill_fireMin = 4, skill_fireMax = 6, skill_fireDotBase = 5.2, }, + [4] = { skill_manaCostBase = 10, skill_fireMin = 6, skill_fireMax = 8, skill_fireDotBase = 7.2, }, + [5] = { skill_manaCostBase = 11, skill_fireMin = 8, skill_fireMax = 12, skill_fireDotBase = 10.6, }, + [6] = { skill_manaCostBase = 12, skill_fireMin = 13, skill_fireMax = 19, skill_fireDotBase = 16.4, }, + [7] = { skill_manaCostBase = 13, skill_fireMin = 18, skill_fireMax = 27, skill_fireDotBase = 22.6, }, + [8] = { skill_manaCostBase = 14, skill_fireMin = 25, skill_fireMax = 37, skill_fireDotBase = 30.5, }, + [9] = { skill_manaCostBase = 14, skill_fireMin = 34, skill_fireMax = 50, skill_fireDotBase = 40.5, }, + [10] = { skill_manaCostBase = 16, skill_fireMin = 45, skill_fireMax = 67, skill_fireDotBase = 53.3, }, + [11] = { skill_manaCostBase = 17, skill_fireMin = 59, skill_fireMax = 89, skill_fireDotBase = 69.5, }, + [12] = { skill_manaCostBase = 18, skill_fireMin = 78, skill_fireMax = 117, skill_fireDotBase = 89.9, }, + [13] = { skill_manaCostBase = 19, skill_fireMin = 101, skill_fireMax = 152, skill_fireDotBase = 115.4, }, + [14] = { skill_manaCostBase = 20, skill_fireMin = 132, skill_fireMax = 197, skill_fireDotBase = 147.4, }, + [15] = { skill_manaCostBase = 21, skill_fireMin = 170, skill_fireMax = 255, skill_fireDotBase = 187.2, }, + [16] = { skill_manaCostBase = 22, skill_fireMin = 219, skill_fireMax = 328, skill_fireDotBase = 236.8, }, + [17] = { skill_manaCostBase = 22, skill_fireMin = 280, skill_fireMax = 420, skill_fireDotBase = 298.3, }, + [18] = { skill_manaCostBase = 23, skill_fireMin = 358, skill_fireMax = 536, skill_fireDotBase = 374.4, }, + [19] = { skill_manaCostBase = 24, skill_fireMin = 429, skill_fireMax = 643, skill_fireDotBase = 441.1, }, + [20] = { skill_manaCostBase = 24, skill_fireMin = 513, skill_fireMax = 770, skill_fireDotBase = 518.8, }, + [21] = { skill_manaCostBase = 25, skill_fireMin = 578, skill_fireMax = 867, skill_fireDotBase = 574, }, + [22] = { skill_manaCostBase = 26, skill_fireMin = 651, skill_fireMax = 976, skill_fireDotBase = 634.4, }, + [23] = { skill_manaCostBase = 26, skill_fireMin = 732, skill_fireMax = 1098, skill_fireDotBase = 700.6, }, + [24] = { skill_manaCostBase = 27, skill_fireMin = 823, skill_fireMax = 1235, skill_fireDotBase = 773, }, + [25] = { skill_manaCostBase = 27, skill_fireMin = 925, skill_fireMax = 1388, skill_fireDotBase = 852.1, }, + [26] = { skill_manaCostBase = 28, skill_fireMin = 1040, skill_fireMax = 1559, skill_fireDotBase = 938.5, }, + [27] = { skill_manaCostBase = 29, skill_fireMin = 1167, skill_fireMax = 1751, skill_fireDotBase = 1032.8, }, + [28] = { skill_manaCostBase = 30, skill_fireMin = 1310, skill_fireMax = 1965, skill_fireDotBase = 1135.5, }, + [29] = { skill_manaCostBase = 30, skill_fireMin = 1470, skill_fireMax = 2205, skill_fireDotBase = 1247.3, }, + [30] = { skill_manaCostBase = 30, skill_fireMin = 1648, skill_fireMax = 2472, skill_fireDotBase = 1369, }, + } +} +gems["Flicker Strike"] = { + unsupported = true, +} +gems["Freeze Mine"] = { + spell = true, + mine = true, + aoe = true, + cold = true, + base = { + skill_castTime = 0.5, + skill_damageEff = 0.5, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 6, skill_coldMin = 7, skill_coldMax = 10, }, + [2] = { skill_manaCostBase = 8, skill_coldMin = 9, skill_coldMax = 13, }, + [3] = { skill_manaCostBase = 10, skill_coldMin = 12, skill_coldMax = 17, }, + [4] = { skill_manaCostBase = 10, skill_coldMin = 15, skill_coldMax = 23, }, + [5] = { skill_manaCostBase = 11, skill_coldMin = 19, skill_coldMax = 29, }, + [6] = { skill_manaCostBase = 12, skill_coldMin = 24, skill_coldMax = 37, }, + [7] = { skill_manaCostBase = 13, skill_coldMin = 30, skill_coldMax = 46, }, + [8] = { skill_manaCostBase = 14, skill_coldMin = 36, skill_coldMax = 54, }, + [9] = { skill_manaCostBase = 14, skill_coldMin = 42, skill_coldMax = 63, }, + [10] = { skill_manaCostBase = 16, skill_coldMin = 49, skill_coldMax = 73, }, + [11] = { skill_manaCostBase = 18, skill_coldMin = 57, skill_coldMax = 85, }, + [12] = { skill_manaCostBase = 18, skill_coldMin = 66, skill_coldMax = 99, }, + [13] = { skill_manaCostBase = 19, skill_coldMin = 76, skill_coldMax = 114, }, + [14] = { skill_manaCostBase = 20, skill_coldMin = 88, skill_coldMax = 131, }, + [15] = { skill_manaCostBase = 21, skill_coldMin = 101, skill_coldMax = 151, }, + [16] = { skill_manaCostBase = 21, skill_coldMin = 116, skill_coldMax = 173, }, + [17] = { skill_manaCostBase = 21, skill_coldMin = 132, skill_coldMax = 199, }, + [18] = { skill_manaCostBase = 21, skill_coldMin = 151, skill_coldMax = 227, }, + [19] = { skill_manaCostBase = 22, skill_coldMin = 165, skill_coldMax = 248, }, + [20] = { skill_manaCostBase = 22, skill_coldMin = 181, skill_coldMax = 271, }, + [21] = { skill_manaCostBase = 22, skill_coldMin = 197, skill_coldMax = 296, }, + [22] = { skill_manaCostBase = 22, skill_coldMin = 215, skill_coldMax = 322, }, + [23] = { skill_manaCostBase = 23, skill_coldMin = 234, skill_coldMax = 351, }, + [24] = { skill_manaCostBase = 23, skill_coldMin = 255, skill_coldMax = 383, }, + [25] = { skill_manaCostBase = 24, skill_coldMin = 278, skill_coldMax = 417, }, + [26] = { skill_manaCostBase = 24, skill_coldMin = 302, skill_coldMax = 454, }, + [27] = { skill_manaCostBase = 24, skill_coldMin = 329, skill_coldMax = 493, }, + [28] = { skill_manaCostBase = 24, skill_coldMin = 358, skill_coldMax = 536, }, + [29] = { skill_manaCostBase = 25, skill_coldMin = 389, skill_coldMax = 583, }, + [30] = { skill_manaCostBase = 25, skill_coldMin = 422, skill_coldMax = 633, }, + } +} +gems["Frenzy"] = { + attack = true, + melee = true, + bow = true, + projectile = true, + base = { + skill_manaCostBase = 10, + frenzy_attack_physicalInc = 5, + frenzy_attackSpeedInc = 5, + }, + quality = { + attackSpeedInc = 0.5, + }, + levels = { + [1] = { attack_damageMore = 1.1, }, + [2] = { attack_damageMore = 1.114, }, + [3] = { attack_damageMore = 1.128, }, + [4] = { attack_damageMore = 1.142, }, + [5] = { attack_damageMore = 1.156, }, + [6] = { attack_damageMore = 1.17, }, + [7] = { attack_damageMore = 1.184, }, + [8] = { attack_damageMore = 1.198, }, + [9] = { attack_damageMore = 1.212, }, + [10] = { attack_damageMore = 1.226, }, + [11] = { attack_damageMore = 1.24, }, + [12] = { attack_damageMore = 1.254, }, + [13] = { attack_damageMore = 1.268, }, + [14] = { attack_damageMore = 1.282, }, + [15] = { attack_damageMore = 1.296, }, + [16] = { attack_damageMore = 1.31, }, + [17] = { attack_damageMore = 1.324, }, + [18] = { attack_damageMore = 1.338, }, + [19] = { attack_damageMore = 1.352, }, + [20] = { attack_damageMore = 1.366, }, + [21] = { attack_damageMore = 1.38, }, + [22] = { attack_damageMore = 1.394, }, + [23] = { attack_damageMore = 1.408, }, + [24] = { attack_damageMore = 1.422, }, + [25] = { attack_damageMore = 1.436, }, + [26] = { attack_damageMore = 1.45, }, + [27] = { attack_damageMore = 1.464, }, + [28] = { attack_damageMore = 1.478, }, + [29] = { attack_damageMore = 1.492, }, + [30] = { attack_damageMore = 1.506, }, + } +} +gems["Frost Blades"] = { + attack = true, + melee = true, + projectile = true, + cold = true, + parts = { + { + name = "Melee hit", + melee = true, + projectile = false, + }, + { + name = "Icy blades", + melee = false, + projectile = true, + }, + }, + base = { + skill_manaCostBase = 6, + physicalGainAscold = 40, + }, + quality = { + projectile_damageInc = 1, + }, + levels = { + [1] = { attack_damageMore = 1, }, + [2] = { attack_damageMore = 1.012, }, + [3] = { attack_damageMore = 1.024, }, + [4] = { attack_damageMore = 1.036, }, + [5] = { attack_damageMore = 1.048, }, + [6] = { attack_damageMore = 1.06, }, + [7] = { attack_damageMore = 1.072, }, + [8] = { attack_damageMore = 1.084, }, + [9] = { attack_damageMore = 1.096, }, + [10] = { attack_damageMore = 1.108, }, + [11] = { attack_damageMore = 1.12, }, + [12] = { attack_damageMore = 1.132, }, + [13] = { attack_damageMore = 1.144, }, + [14] = { attack_damageMore = 1.156, }, + [15] = { attack_damageMore = 1.168, }, + [16] = { attack_damageMore = 1.18, }, + [17] = { attack_damageMore = 1.192, }, + [18] = { attack_damageMore = 1.204, }, + [19] = { attack_damageMore = 1.216, }, + [20] = { attack_damageMore = 1.228, }, + [21] = { attack_damageMore = 1.24, }, + [22] = { attack_damageMore = 1.252, }, + [23] = { attack_damageMore = 1.264, }, + [24] = { attack_damageMore = 1.276, }, + [25] = { attack_damageMore = 1.288, }, + [26] = { attack_damageMore = 1.3, }, + [27] = { attack_damageMore = 1.312, }, + [28] = { attack_damageMore = 1.324, }, + [29] = { attack_damageMore = 1.336, }, + [30] = { attack_damageMore = 1.348, }, + } +} +gems["Grace"] = { + aura = true, + spell = true, + aoe = true, + base = { + skill_manaReservedPercent = 50, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { auraRadiusInc = 0, evasionBase = 227, }, + [2] = { auraRadiusInc = 3, evasionBase = 271, }, + [3] = { auraRadiusInc = 6, evasionBase = 322, }, + [4] = { auraRadiusInc = 9, evasionBase = 379, }, + [5] = { auraRadiusInc = 12, evasionBase = 444, }, + [6] = { auraRadiusInc = 15, evasionBase = 528, }, + [7] = { auraRadiusInc = 18, evasionBase = 621, }, + [8] = { auraRadiusInc = 21, evasionBase = 722, }, + [9] = { auraRadiusInc = 23, evasionBase = 845, }, + [10] = { auraRadiusInc = 25, evasionBase = 940, }, + [11] = { auraRadiusInc = 27, evasionBase = 1043, }, + [12] = { auraRadiusInc = 29, evasionBase = 1155, }, + [13] = { auraRadiusInc = 31, evasionBase = 1283, }, + [14] = { auraRadiusInc = 33, evasionBase = 1413, }, + [15] = { auraRadiusInc = 35, evasionBase = 1567, }, + [16] = { auraRadiusInc = 36, evasionBase = 1732, }, + [17] = { auraRadiusInc = 37, evasionBase = 1914, }, + [18] = { auraRadiusInc = 38, evasionBase = 2115, }, + [19] = { auraRadiusInc = 39, evasionBase = 2335, }, + [20] = { auraRadiusInc = 40, evasionBase = 2575, }, + [21] = { auraRadiusInc = 41, evasionBase = 2700, }, + [22] = { auraRadiusInc = 42, evasionBase = 2835, }, + [23] = { auraRadiusInc = 43, evasionBase = 2979, }, + [24] = { auraRadiusInc = 44, evasionBase = 3124, }, + [25] = { auraRadiusInc = 45, evasionBase = 3279, }, + [26] = { auraRadiusInc = 46, evasionBase = 3444, }, + [27] = { auraRadiusInc = 47, evasionBase = 3611, }, + [28] = { auraRadiusInc = 48, evasionBase = 3795, }, + [29] = { auraRadiusInc = 49, evasionBase = 3982, }, + [30] = { auraRadiusInc = 50, evasionBase = 4179, }, + } +} +gems["Haste"] = { + aura = true, + spell = true, + aoe = true, + base = { + skill_manaReservedPercent = 50, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { auraRadiusInc = 0, attackSpeedInc = 9, castSpeedInc = 9, movementSpeedInc = 4, }, + [2] = { auraRadiusInc = 3, attackSpeedInc = 10, castSpeedInc = 9, movementSpeedInc = 4, }, + [3] = { auraRadiusInc = 6, attackSpeedInc = 10, castSpeedInc = 10, movementSpeedInc = 4, }, + [4] = { auraRadiusInc = 9, attackSpeedInc = 10, castSpeedInc = 10, movementSpeedInc = 5, }, + [5] = { auraRadiusInc = 12, attackSpeedInc = 11, castSpeedInc = 10, movementSpeedInc = 5, }, + [6] = { auraRadiusInc = 15, attackSpeedInc = 11, castSpeedInc = 11, movementSpeedInc = 5, }, + [7] = { auraRadiusInc = 18, attackSpeedInc = 11, castSpeedInc = 11, movementSpeedInc = 6, }, + [8] = { auraRadiusInc = 21, attackSpeedInc = 12, castSpeedInc = 11, movementSpeedInc = 6, }, + [9] = { auraRadiusInc = 23, attackSpeedInc = 12, castSpeedInc = 12, movementSpeedInc = 6, }, + [10] = { auraRadiusInc = 25, attackSpeedInc = 12, castSpeedInc = 12, movementSpeedInc = 7, }, + [11] = { auraRadiusInc = 27, attackSpeedInc = 13, castSpeedInc = 12, movementSpeedInc = 7, }, + [12] = { auraRadiusInc = 29, attackSpeedInc = 13, castSpeedInc = 13, movementSpeedInc = 7, }, + [13] = { auraRadiusInc = 31, attackSpeedInc = 13, castSpeedInc = 13, movementSpeedInc = 8, }, + [14] = { auraRadiusInc = 33, attackSpeedInc = 14, castSpeedInc = 13, movementSpeedInc = 8, }, + [15] = { auraRadiusInc = 35, attackSpeedInc = 14, castSpeedInc = 14, movementSpeedInc = 8, }, + [16] = { auraRadiusInc = 36, attackSpeedInc = 15, castSpeedInc = 14, movementSpeedInc = 8, }, + [17] = { auraRadiusInc = 37, attackSpeedInc = 15, castSpeedInc = 15, movementSpeedInc = 8, }, + [18] = { auraRadiusInc = 38, attackSpeedInc = 16, castSpeedInc = 15, movementSpeedInc = 8, }, + [19] = { auraRadiusInc = 39, attackSpeedInc = 16, castSpeedInc = 16, movementSpeedInc = 8, }, + [20] = { auraRadiusInc = 40, attackSpeedInc = 16, castSpeedInc = 16, movementSpeedInc = 9, }, + [21] = { auraRadiusInc = 41, attackSpeedInc = 17, castSpeedInc = 16, movementSpeedInc = 9, }, + [22] = { auraRadiusInc = 42, attackSpeedInc = 17, castSpeedInc = 17, movementSpeedInc = 9, }, + [23] = { auraRadiusInc = 43, attackSpeedInc = 17, castSpeedInc = 17, movementSpeedInc = 10, }, + [24] = { auraRadiusInc = 44, attackSpeedInc = 18, castSpeedInc = 17, movementSpeedInc = 10, }, + [25] = { auraRadiusInc = 45, attackSpeedInc = 18, castSpeedInc = 18, movementSpeedInc = 10, }, + [26] = { auraRadiusInc = 46, attackSpeedInc = 18, castSpeedInc = 18, movementSpeedInc = 11, }, + [27] = { auraRadiusInc = 47, attackSpeedInc = 19, castSpeedInc = 18, movementSpeedInc = 11, }, + [28] = { auraRadiusInc = 48, attackSpeedInc = 19, castSpeedInc = 19, movementSpeedInc = 11, }, + [29] = { auraRadiusInc = 49, attackSpeedInc = 19, castSpeedInc = 19, movementSpeedInc = 12, }, + [30] = { auraRadiusInc = 50, attackSpeedInc = 20, castSpeedInc = 19, movementSpeedInc = 12, }, + } +} +gems["Hatred"] = { + aura = true, + spell = true, + aoe = true, + cold = true, + base = { + skill_manaReservedPercent = 50, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { auraRadiusInc = 0, physicalGainAscold = 26, }, + [2] = { auraRadiusInc = 3, physicalGainAscold = 26, }, + [3] = { auraRadiusInc = 6, physicalGainAscold = 27, }, + [4] = { auraRadiusInc = 9, physicalGainAscold = 27, }, + [5] = { auraRadiusInc = 12, physicalGainAscold = 28, }, + [6] = { auraRadiusInc = 15, physicalGainAscold = 28, }, + [7] = { auraRadiusInc = 18, physicalGainAscold = 29, }, + [8] = { auraRadiusInc = 21, physicalGainAscold = 29, }, + [9] = { auraRadiusInc = 23, physicalGainAscold = 30, }, + [10] = { auraRadiusInc = 25, physicalGainAscold = 30, }, + [11] = { auraRadiusInc = 27, physicalGainAscold = 31, }, + [12] = { auraRadiusInc = 29, physicalGainAscold = 31, }, + [13] = { auraRadiusInc = 31, physicalGainAscold = 32, }, + [14] = { auraRadiusInc = 33, physicalGainAscold = 32, }, + [15] = { auraRadiusInc = 35, physicalGainAscold = 33, }, + [16] = { auraRadiusInc = 36, physicalGainAscold = 34, }, + [17] = { auraRadiusInc = 37, physicalGainAscold = 34, }, + [18] = { auraRadiusInc = 38, physicalGainAscold = 35, }, + [19] = { auraRadiusInc = 39, physicalGainAscold = 35, }, + [20] = { auraRadiusInc = 40, physicalGainAscold = 36, }, + [21] = { auraRadiusInc = 41, physicalGainAscold = 36, }, + [22] = { auraRadiusInc = 42, physicalGainAscold = 37, }, + [23] = { auraRadiusInc = 43, physicalGainAscold = 37, }, + [24] = { auraRadiusInc = 44, physicalGainAscold = 38, }, + [25] = { auraRadiusInc = 45, physicalGainAscold = 38, }, + [26] = { auraRadiusInc = 46, physicalGainAscold = 39, }, + [27] = { auraRadiusInc = 47, physicalGainAscold = 39, }, + [28] = { auraRadiusInc = 48, physicalGainAscold = 40, }, + [29] = { auraRadiusInc = 49, physicalGainAscold = 40, }, + [30] = { auraRadiusInc = 50, physicalGainAscold = 41, }, + } +} +gems["Herald of Ice"] = { + cast = true, + aoe = true, + cold = true, + base = { + skill_manaReservedPercent = 25, + skill_damageEff = 0.8, + }, + quality = { + buff_coldInc = 0.75, + }, + levels = { + [1] = { buff_spell_coldMin = 4, buff_spell_coldMax = 5, buff_attack_coldMin = 4, buff_attack_coldMax = 5, skill_coldMin = 18, skill_coldMax = 26, }, + [2] = { buff_spell_coldMin = 5, buff_spell_coldMax = 7, buff_attack_coldMin = 5, buff_attack_coldMax = 7, skill_coldMin = 23, skill_coldMax = 35, }, + [3] = { buff_spell_coldMin = 6, buff_spell_coldMax = 8, buff_attack_coldMin = 6, buff_attack_coldMax = 8, skill_coldMin = 30, skill_coldMax = 45, }, + [4] = { buff_spell_coldMin = 7, buff_spell_coldMax = 10, buff_attack_coldMin = 7, buff_attack_coldMax = 10, skill_coldMin = 38, skill_coldMax = 57, }, + [5] = { buff_spell_coldMin = 8, buff_spell_coldMax = 12, buff_attack_coldMin = 8, buff_attack_coldMax = 12, skill_coldMin = 45, skill_coldMax = 67, }, + [6] = { buff_spell_coldMin = 9, buff_spell_coldMax = 14, buff_attack_coldMin = 9, buff_attack_coldMax = 14, skill_coldMin = 53, skill_coldMax = 80, }, + [7] = { buff_spell_coldMin = 10, buff_spell_coldMax = 16, buff_attack_coldMin = 10, buff_attack_coldMax = 16, skill_coldMin = 62, skill_coldMax = 94, }, + [8] = { buff_spell_coldMin = 12, buff_spell_coldMax = 18, buff_attack_coldMin = 12, buff_attack_coldMax = 18, skill_coldMin = 73, skill_coldMax = 110, }, + [9] = { buff_spell_coldMin = 13, buff_spell_coldMax = 20, buff_attack_coldMin = 13, buff_attack_coldMax = 20, skill_coldMin = 85, skill_coldMax = 128, }, + [10] = { buff_spell_coldMin = 15, buff_spell_coldMax = 23, buff_attack_coldMin = 15, buff_attack_coldMax = 23, skill_coldMin = 99, skill_coldMax = 149, }, + [11] = { buff_spell_coldMin = 17, buff_spell_coldMax = 26, buff_attack_coldMin = 17, buff_attack_coldMax = 26, skill_coldMin = 115, skill_coldMax = 173, }, + [12] = { buff_spell_coldMin = 19, buff_spell_coldMax = 29, buff_attack_coldMin = 19, buff_attack_coldMax = 29, skill_coldMin = 134, skill_coldMax = 200, }, + [13] = { buff_spell_coldMin = 22, buff_spell_coldMax = 33, buff_attack_coldMin = 22, buff_attack_coldMax = 33, skill_coldMin = 154, skill_coldMax = 232, }, + [14] = { buff_spell_coldMin = 24, buff_spell_coldMax = 37, buff_attack_coldMin = 24, buff_attack_coldMax = 37, skill_coldMin = 178, skill_coldMax = 267, }, + [15] = { buff_spell_coldMin = 26, buff_spell_coldMax = 39, buff_attack_coldMin = 26, buff_attack_coldMax = 39, skill_coldMin = 195, skill_coldMax = 293, }, + [16] = { buff_spell_coldMin = 28, buff_spell_coldMax = 42, buff_attack_coldMin = 28, buff_attack_coldMax = 42, skill_coldMin = 214, skill_coldMax = 321, }, + [17] = { buff_spell_coldMin = 30, buff_spell_coldMax = 46, buff_attack_coldMin = 30, buff_attack_coldMax = 46, skill_coldMin = 235, skill_coldMax = 352, }, + [18] = { buff_spell_coldMin = 33, buff_spell_coldMax = 49, buff_attack_coldMin = 33, buff_attack_coldMax = 49, skill_coldMin = 257, skill_coldMax = 386, }, + [19] = { buff_spell_coldMin = 35, buff_spell_coldMax = 53, buff_attack_coldMin = 35, buff_attack_coldMax = 53, skill_coldMin = 282, skill_coldMax = 422, }, + [20] = { buff_spell_coldMin = 38, buff_spell_coldMax = 56, buff_attack_coldMin = 38, buff_attack_coldMax = 56, skill_coldMin = 308, skill_coldMax = 462, }, + [21] = { buff_spell_coldMin = 40, buff_spell_coldMax = 61, buff_attack_coldMin = 40, buff_attack_coldMax = 61, skill_coldMin = 337, skill_coldMax = 505, }, + [22] = { buff_spell_coldMin = 43, buff_spell_coldMax = 65, buff_attack_coldMin = 43, buff_attack_coldMax = 65, skill_coldMin = 368, skill_coldMax = 552, }, + [23] = { buff_spell_coldMin = 46, buff_spell_coldMax = 70, buff_attack_coldMin = 46, buff_attack_coldMax = 70, skill_coldMin = 402, skill_coldMax = 603, }, + [24] = { buff_spell_coldMin = 50, buff_spell_coldMax = 75, buff_attack_coldMin = 50, buff_attack_coldMax = 75, skill_coldMin = 438, skill_coldMax = 658, }, + [25] = { buff_spell_coldMin = 53, buff_spell_coldMax = 80, buff_attack_coldMin = 53, buff_attack_coldMax = 80, skill_coldMin = 478, skill_coldMax = 717, }, + [26] = { buff_spell_coldMin = 57, buff_spell_coldMax = 85, buff_attack_coldMin = 57, buff_attack_coldMax = 85, skill_coldMin = 521, skill_coldMax = 782, }, + [27] = { buff_spell_coldMin = 61, buff_spell_coldMax = 91, buff_attack_coldMin = 61, buff_attack_coldMax = 91, skill_coldMin = 568, skill_coldMax = 852, }, + [28] = { buff_spell_coldMin = 65, buff_spell_coldMax = 98, buff_attack_coldMin = 65, buff_attack_coldMax = 98, skill_coldMin = 619, skill_coldMax = 928, }, + [29] = { buff_spell_coldMin = 69, buff_spell_coldMax = 104, buff_attack_coldMin = 69, buff_attack_coldMax = 104, skill_coldMin = 674, skill_coldMax = 1010, }, + [30] = { buff_spell_coldMin = 74, buff_spell_coldMax = 111, buff_attack_coldMin = 74, buff_attack_coldMax = 111, skill_coldMin = 733, skill_coldMax = 1100, }, + } +} +gems["Ice Shot"] = { + attack = true, + bow = true, + projectile = true, + aoe = true, + duration = true, + cold = true, + parts = { + { + name = "Arrow", + aoe = false, + }, + { + name = "Cone", + aoe = true, + }, + }, + base = { + skill_durationBase = 1.5, + part1_physicalGainAscold = 40, + part2_physicalGainAscold = 100, + }, + quality = { + coldInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 6, attack_damageMore = 1.2, }, + [2] = { skill_manaCostBase = 6, attack_damageMore = 1.214, }, + [3] = { skill_manaCostBase = 6, attack_damageMore = 1.228, }, + [4] = { skill_manaCostBase = 7, attack_damageMore = 1.242, }, + [5] = { skill_manaCostBase = 7, attack_damageMore = 1.256, }, + [6] = { skill_manaCostBase = 7, attack_damageMore = 1.27, }, + [7] = { skill_manaCostBase = 7, attack_damageMore = 1.284, }, + [8] = { skill_manaCostBase = 8, attack_damageMore = 1.298, }, + [9] = { skill_manaCostBase = 8, attack_damageMore = 1.312, }, + [10] = { skill_manaCostBase = 8, attack_damageMore = 1.326, }, + [11] = { skill_manaCostBase = 8, attack_damageMore = 1.34, }, + [12] = { skill_manaCostBase = 8, attack_damageMore = 1.354, }, + [13] = { skill_manaCostBase = 9, attack_damageMore = 1.368, }, + [14] = { skill_manaCostBase = 9, attack_damageMore = 1.382, }, + [15] = { skill_manaCostBase = 9, attack_damageMore = 1.396, }, + [16] = { skill_manaCostBase = 9, attack_damageMore = 1.41, }, + [17] = { skill_manaCostBase = 9, attack_damageMore = 1.424, }, + [18] = { skill_manaCostBase = 10, attack_damageMore = 1.438, }, + [19] = { skill_manaCostBase = 10, attack_damageMore = 1.452, }, + [20] = { skill_manaCostBase = 10, attack_damageMore = 1.466, }, + [21] = { skill_manaCostBase = 10, attack_damageMore = 1.48, }, + [22] = { skill_manaCostBase = 10, attack_damageMore = 1.494, }, + [23] = { skill_manaCostBase = 11, attack_damageMore = 1.508, }, + [24] = { skill_manaCostBase = 11, attack_damageMore = 1.522, }, + [25] = { skill_manaCostBase = 11, attack_damageMore = 1.536, }, + [26] = { skill_manaCostBase = 11, attack_damageMore = 1.55, }, + [27] = { skill_manaCostBase = 11, attack_damageMore = 1.564, }, + [28] = { skill_manaCostBase = 12, attack_damageMore = 1.578, }, + [29] = { skill_manaCostBase = 12, attack_damageMore = 1.592, }, + [30] = { skill_manaCostBase = 12, attack_damageMore = 1.606, }, + } +} +gems["Ice Trap"] = { + spell = true, + trap = true, + aoe = true, + cold = true, + base = { + skill_castTime = 1, + skill_damageEff = 1.1, + skill_critChanceBase = 5, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 13, skill_coldMin = 60, skill_coldMax = 90, }, + [2] = { skill_manaCostBase = 14, skill_coldMin = 72, skill_coldMax = 108, }, + [3] = { skill_manaCostBase = 15, skill_coldMin = 85, skill_coldMax = 128, }, + [4] = { skill_manaCostBase = 15, skill_coldMin = 101, skill_coldMax = 151, }, + [5] = { skill_manaCostBase = 16, skill_coldMin = 119, skill_coldMax = 178, }, + [6] = { skill_manaCostBase = 17, skill_coldMin = 132, skill_coldMax = 198, }, + [7] = { skill_manaCostBase = 17, skill_coldMin = 147, skill_coldMax = 220, }, + [8] = { skill_manaCostBase = 18, skill_coldMin = 163, skill_coldMax = 244, }, + [9] = { skill_manaCostBase = 19, skill_coldMin = 180, skill_coldMax = 270, }, + [10] = { skill_manaCostBase = 19, skill_coldMin = 199, skill_coldMax = 299, }, + [11] = { skill_manaCostBase = 20, skill_coldMin = 220, skill_coldMax = 330, }, + [12] = { skill_manaCostBase = 20, skill_coldMin = 243, skill_coldMax = 364, }, + [13] = { skill_manaCostBase = 21, skill_coldMin = 268, skill_coldMax = 402, }, + [14] = { skill_manaCostBase = 21, skill_coldMin = 295, skill_coldMax = 442, }, + [15] = { skill_manaCostBase = 22, skill_coldMin = 325, skill_coldMax = 487, }, + [16] = { skill_manaCostBase = 23, skill_coldMin = 357, skill_coldMax = 536, }, + [17] = { skill_manaCostBase = 23, skill_coldMin = 392, skill_coldMax = 589, }, + [18] = { skill_manaCostBase = 24, skill_coldMin = 431, skill_coldMax = 646, }, + [19] = { skill_manaCostBase = 24, skill_coldMin = 473, skill_coldMax = 709, }, + [20] = { skill_manaCostBase = 25, skill_coldMin = 519, skill_coldMax = 778, }, + [21] = { skill_manaCostBase = 26, skill_coldMin = 568, skill_coldMax = 853, }, + [22] = { skill_manaCostBase = 26, skill_coldMin = 623, skill_coldMax = 934, }, + [23] = { skill_manaCostBase = 27, skill_coldMin = 681, skill_coldMax = 1022, }, + [24] = { skill_manaCostBase = 27, skill_coldMin = 746, skill_coldMax = 1118, }, + [25] = { skill_manaCostBase = 28, skill_coldMin = 815, skill_coldMax = 1223, }, + [26] = { skill_manaCostBase = 28, skill_coldMin = 891, skill_coldMax = 1337, }, + [27] = { skill_manaCostBase = 29, skill_coldMin = 973, skill_coldMax = 1460, }, + [28] = { skill_manaCostBase = 30, skill_coldMin = 1063, skill_coldMax = 1595, }, + [29] = { skill_manaCostBase = 30, skill_coldMin = 1160, skill_coldMax = 1740, }, + [30] = { skill_manaCostBase = 31, skill_coldMin = 1266, skill_coldMax = 1899, }, + } +} +gems["Lightning Arrow"] = { + attack = true, + bow = true, + projectile = true, + aoe = true, + lightning = true, + parts = { + { + aoe = false, + }, + }, + base = { + physicalConvertTolightning = 50, + }, + quality = { + shockChance = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 7, attack_damageMore = 1, }, + [2] = { skill_manaCostBase = 7, attack_damageMore = 1.01, }, + [3] = { skill_manaCostBase = 7, attack_damageMore = 1.02, }, + [4] = { skill_manaCostBase = 8, attack_damageMore = 1.03, }, + [5] = { skill_manaCostBase = 8, attack_damageMore = 1.04, }, + [6] = { skill_manaCostBase = 8, attack_damageMore = 1.05, }, + [7] = { skill_manaCostBase = 8, attack_damageMore = 1.06, }, + [8] = { skill_manaCostBase = 8, attack_damageMore = 1.07, }, + [9] = { skill_manaCostBase = 9, attack_damageMore = 1.08, }, + [10] = { skill_manaCostBase = 9, attack_damageMore = 1.09, }, + [11] = { skill_manaCostBase = 9, attack_damageMore = 1.1, }, + [12] = { skill_manaCostBase = 9, attack_damageMore = 1.11, }, + [13] = { skill_manaCostBase = 9, attack_damageMore = 1.12, }, + [14] = { skill_manaCostBase = 10, attack_damageMore = 1.13, }, + [15] = { skill_manaCostBase = 10, attack_damageMore = 1.14, }, + [16] = { skill_manaCostBase = 10, attack_damageMore = 1.15, }, + [17] = { skill_manaCostBase = 10, attack_damageMore = 1.16, }, + [18] = { skill_manaCostBase = 10, attack_damageMore = 1.17, }, + [19] = { skill_manaCostBase = 11, attack_damageMore = 1.18, }, + [20] = { skill_manaCostBase = 11, attack_damageMore = 1.19, }, + [21] = { skill_manaCostBase = 11, attack_damageMore = 1.2, }, + [22] = { skill_manaCostBase = 11, attack_damageMore = 1.21, }, + [23] = { skill_manaCostBase = 11, attack_damageMore = 1.22, }, + [24] = { skill_manaCostBase = 11, attack_damageMore = 1.23, }, + [25] = { skill_manaCostBase = 11, attack_damageMore = 1.24, }, + [26] = { skill_manaCostBase = 12, attack_damageMore = 1.25, }, + [27] = { skill_manaCostBase = 12, attack_damageMore = 1.26, }, + [28] = { skill_manaCostBase = 12, attack_damageMore = 1.27, }, + [29] = { skill_manaCostBase = 12, attack_damageMore = 1.28, }, + [30] = { skill_manaCostBase = 12, attack_damageMore = 1.29, }, + } +} +gems["Lightning Strike"] = { + attack = true, + melee = true, + projectile = true, + lightning = true, + parts = { + { + name = "Melee hit", + melee = true, + projectile = false, + }, + { + name = "Projectiles", + melee = false, + projectile = true, + }, + }, + base = { + skill_manaCostBase = 6, + physicalConvertTolightning = 50, + part2_damageMore = 0.75, + }, + quality = { + pierceChance = 2, + }, + levels = { + [1] = { attack_damageMore = 1.3, }, + [2] = { attack_damageMore = 1.316, }, + [3] = { attack_damageMore = 1.332, }, + [4] = { attack_damageMore = 1.348, }, + [5] = { attack_damageMore = 1.364, }, + [6] = { attack_damageMore = 1.38, }, + [7] = { attack_damageMore = 1.396, }, + [8] = { attack_damageMore = 1.412, }, + [9] = { attack_damageMore = 1.428, }, + [10] = { attack_damageMore = 1.444, }, + [11] = { attack_damageMore = 1.46, }, + [12] = { attack_damageMore = 1.476, }, + [13] = { attack_damageMore = 1.492, }, + [14] = { attack_damageMore = 1.508, }, + [15] = { attack_damageMore = 1.524, }, + [16] = { attack_damageMore = 1.54, }, + [17] = { attack_damageMore = 1.556, }, + [18] = { attack_damageMore = 1.572, }, + [19] = { attack_damageMore = 1.588, }, + [20] = { attack_damageMore = 1.604, }, + [21] = { attack_damageMore = 1.62, }, + [22] = { attack_damageMore = 1.636, }, + [23] = { attack_damageMore = 1.652, }, + [24] = { attack_damageMore = 1.668, }, + [25] = { attack_damageMore = 1.684, }, + [26] = { attack_damageMore = 1.7, }, + [27] = { attack_damageMore = 1.716, }, + [28] = { attack_damageMore = 1.732, }, + [29] = { attack_damageMore = 1.748, }, + [30] = { attack_damageMore = 1.764, }, + } +} +gems["Mirror Arrow"] = { + unsupported = true, +} +gems["Phase Run"] = { + unsupported = true, +} +gems["Poacher's Mark"] = { + unsupported = true, +} +gems["Projectile Weakness"] = { + unsupported = true, +} +gems["Puncture"] = { + attack = true, + bow = true, + projectile = true, + melee = true, + duration = true, + base = { + skill_manaCostBase = 6, + bleedChance = 100, + }, + quality = { + durationInc = 1, + }, + levels = { + [1] = { attack_damageMore = 1, }, + [2] = { attack_damageMore = 1.012, }, + [3] = { attack_damageMore = 1.024, }, + [4] = { attack_damageMore = 1.036, }, + [5] = { attack_damageMore = 1.048, }, + [6] = { attack_damageMore = 1.06, }, + [7] = { attack_damageMore = 1.072, }, + [8] = { attack_damageMore = 1.084, }, + [9] = { attack_damageMore = 1.096, }, + [10] = { attack_damageMore = 1.108, }, + [11] = { attack_damageMore = 1.12, }, + [12] = { attack_damageMore = 1.132, }, + [13] = { attack_damageMore = 1.144, }, + [14] = { attack_damageMore = 1.156, }, + [15] = { attack_damageMore = 1.168, }, + [16] = { attack_damageMore = 1.18, }, + [17] = { attack_damageMore = 1.192, }, + [18] = { attack_damageMore = 1.204, }, + [19] = { attack_damageMore = 1.216, }, + [20] = { attack_damageMore = 1.228, }, + [21] = { attack_damageMore = 1.24, }, + [22] = { attack_damageMore = 1.252, }, + [23] = { attack_damageMore = 1.264, }, + [24] = { attack_damageMore = 1.276, }, + [25] = { attack_damageMore = 1.288, }, + [26] = { attack_damageMore = 1.3, }, + [27] = { attack_damageMore = 1.312, }, + [28] = { attack_damageMore = 1.324, }, + [29] = { attack_damageMore = 1.336, }, + [30] = { attack_damageMore = 1.348, }, + } +} +gems["Purity of Ice"] = { + aura = true, + spell = true, + aoe = true, + fire = true, + base = { + skill_manaReservedPercent = 35, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { auraRadiusInc = 0, coldResistBase = 22, coldResistMaxBase = 0, }, + [2] = { auraRadiusInc = 3, coldResistBase = 23, coldResistMaxBase = 0, }, + [3] = { auraRadiusInc = 6, coldResistBase = 24, coldResistMaxBase = 0, }, + [4] = { auraRadiusInc = 9, coldResistBase = 25, coldResistMaxBase = 0, }, + [5] = { auraRadiusInc = 12, coldResistBase = 26, coldResistMaxBase = 1, }, + [6] = { auraRadiusInc = 15, coldResistBase = 27, coldResistMaxBase = 1, }, + [7] = { auraRadiusInc = 18, coldResistBase = 28, coldResistMaxBase = 1, }, + [8] = { auraRadiusInc = 21, coldResistBase = 29, coldResistMaxBase = 1, }, + [9] = { auraRadiusInc = 23, coldResistBase = 30, coldResistMaxBase = 1, }, + [10] = { auraRadiusInc = 25, coldResistBase = 31, coldResistMaxBase = 1, }, + [11] = { auraRadiusInc = 27, coldResistBase = 32, coldResistMaxBase = 2, }, + [12] = { auraRadiusInc = 29, coldResistBase = 33, coldResistMaxBase = 2, }, + [13] = { auraRadiusInc = 31, coldResistBase = 34, coldResistMaxBase = 2, }, + [14] = { auraRadiusInc = 33, coldResistBase = 35, coldResistMaxBase = 2, }, + [15] = { auraRadiusInc = 35, coldResistBase = 36, coldResistMaxBase = 2, }, + [16] = { auraRadiusInc = 36, coldResistBase = 37, coldResistMaxBase = 2, }, + [17] = { auraRadiusInc = 37, coldResistBase = 38, coldResistMaxBase = 3, }, + [18] = { auraRadiusInc = 38, coldResistBase = 39, coldResistMaxBase = 3, }, + [19] = { auraRadiusInc = 39, coldResistBase = 40, coldResistMaxBase = 3, }, + [20] = { auraRadiusInc = 40, coldResistBase = 41, coldResistMaxBase = 4, }, + [21] = { auraRadiusInc = 41, coldResistBase = 42, coldResistMaxBase = 4, }, + [22] = { auraRadiusInc = 42, coldResistBase = 43, coldResistMaxBase = 4, }, + [23] = { auraRadiusInc = 43, coldResistBase = 44, coldResistMaxBase = 5, }, + [24] = { auraRadiusInc = 44, coldResistBase = 45, coldResistMaxBase = 5, }, + [25] = { auraRadiusInc = 45, coldResistBase = 46, coldResistMaxBase = 5, }, + [26] = { auraRadiusInc = 46, coldResistBase = 47, coldResistMaxBase = 5, }, + [27] = { auraRadiusInc = 47, coldResistBase = 48, coldResistMaxBase = 5, }, + [28] = { auraRadiusInc = 48, coldResistBase = 49, coldResistMaxBase = 5, }, + [29] = { auraRadiusInc = 49, coldResistBase = 50, coldResistMaxBase = 5, }, + [30] = { auraRadiusInc = 50, coldResistBase = 51, coldResistMaxBase = 5, }, + } +} +gems["Rain of Arrows"] = { + attack = true, + bow = true, + projectile = true, + aoe = true, + base = { + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 7, attack_damageMore = 1.1, aoeRadiusInc = 0, }, + [2] = { skill_manaCostBase = 7, attack_damageMore = 1.11, aoeRadiusInc = 1, }, + [3] = { skill_manaCostBase = 7, attack_damageMore = 1.12, aoeRadiusInc = 2, }, + [4] = { skill_manaCostBase = 8, attack_damageMore = 1.13, aoeRadiusInc = 3, }, + [5] = { skill_manaCostBase = 8, attack_damageMore = 1.14, aoeRadiusInc = 4, }, + [6] = { skill_manaCostBase = 8, attack_damageMore = 1.15, aoeRadiusInc = 5, }, + [7] = { skill_manaCostBase = 8, attack_damageMore = 1.16, aoeRadiusInc = 6, }, + [8] = { skill_manaCostBase = 8, attack_damageMore = 1.17, aoeRadiusInc = 7, }, + [9] = { skill_manaCostBase = 9, attack_damageMore = 1.18, aoeRadiusInc = 8, }, + [10] = { skill_manaCostBase = 9, attack_damageMore = 1.19, aoeRadiusInc = 9, }, + [11] = { skill_manaCostBase = 9, attack_damageMore = 1.2, aoeRadiusInc = 10, }, + [12] = { skill_manaCostBase = 9, attack_damageMore = 1.21, aoeRadiusInc = 11, }, + [13] = { skill_manaCostBase = 9, attack_damageMore = 1.22, aoeRadiusInc = 12, }, + [14] = { skill_manaCostBase = 10, attack_damageMore = 1.23, aoeRadiusInc = 13, }, + [15] = { skill_manaCostBase = 10, attack_damageMore = 1.24, aoeRadiusInc = 14, }, + [16] = { skill_manaCostBase = 10, attack_damageMore = 1.25, aoeRadiusInc = 15, }, + [17] = { skill_manaCostBase = 10, attack_damageMore = 1.26, aoeRadiusInc = 16, }, + [18] = { skill_manaCostBase = 10, attack_damageMore = 1.27, aoeRadiusInc = 17, }, + [19] = { skill_manaCostBase = 11, attack_damageMore = 1.28, aoeRadiusInc = 18, }, + [20] = { skill_manaCostBase = 11, attack_damageMore = 1.29, aoeRadiusInc = 19, }, + [21] = { skill_manaCostBase = 11, attack_damageMore = 1.3, aoeRadiusInc = 20, }, + [22] = { skill_manaCostBase = 11, attack_damageMore = 1.31, aoeRadiusInc = 21, }, + [23] = { skill_manaCostBase = 11, attack_damageMore = 1.32, aoeRadiusInc = 22, }, + [24] = { skill_manaCostBase = 11, attack_damageMore = 1.33, aoeRadiusInc = 23, }, + [25] = { skill_manaCostBase = 11, attack_damageMore = 1.34, aoeRadiusInc = 24, }, + [26] = { skill_manaCostBase = 12, attack_damageMore = 1.35, aoeRadiusInc = 25, }, + [27] = { skill_manaCostBase = 12, attack_damageMore = 1.36, aoeRadiusInc = 26, }, + [28] = { skill_manaCostBase = 12, attack_damageMore = 1.37, aoeRadiusInc = 27, }, + [29] = { skill_manaCostBase = 12, attack_damageMore = 1.38, aoeRadiusInc = 28, }, + [30] = { skill_manaCostBase = 12, attack_damageMore = 1.39, aoeRadiusInc = 29, }, + } +} +gems["Reave"] = { + attack = true, + melee = true, + aoe = true, + base = { + skill_manaCostBase = 6, + }, + quality = { + attackSpeedInc = 0.5, + }, + levels = { + [1] = { attack_damageMore = 1, }, + [2] = { attack_damageMore = 1.012, }, + [3] = { attack_damageMore = 1.024, }, + [4] = { attack_damageMore = 1.036, }, + [5] = { attack_damageMore = 1.048, }, + [6] = { attack_damageMore = 1.06, }, + [7] = { attack_damageMore = 1.072, }, + [8] = { attack_damageMore = 1.084, }, + [9] = { attack_damageMore = 1.096, }, + [10] = { attack_damageMore = 1.108, }, + [11] = { attack_damageMore = 1.12, }, + [12] = { attack_damageMore = 1.132, }, + [13] = { attack_damageMore = 1.144, }, + [14] = { attack_damageMore = 1.156, }, + [15] = { attack_damageMore = 1.168, }, + [16] = { attack_damageMore = 1.18, }, + [17] = { attack_damageMore = 1.192, }, + [18] = { attack_damageMore = 1.204, }, + [19] = { attack_damageMore = 1.216, }, + [20] = { attack_damageMore = 1.228, }, + [21] = { attack_damageMore = 1.24, }, + [22] = { attack_damageMore = 1.252, }, + [23] = { attack_damageMore = 1.264, }, + [24] = { attack_damageMore = 1.276, }, + [25] = { attack_damageMore = 1.288, }, + [26] = { attack_damageMore = 1.3, }, + [27] = { attack_damageMore = 1.312, }, + [28] = { attack_damageMore = 1.324, }, + [29] = { attack_damageMore = 1.336, }, + [30] = { attack_damageMore = 1.348, }, + } +} +gems["Riposte"] = { + unsupported = true, +} +gems["Shrapnel Shot"] = { + attack = true, + bow = true, + projectile = true, + aoe = true, + lightning = true, + parts = { + { + name = "Arrow", + aoe = false, + }, + { + name = "Cone", + aoe = true, + }, + }, + base = { + pierceChance = 100, + physicalConvertTolightning = 40, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 6, attack_damageMore = 0.8, }, + [2] = { skill_manaCostBase = 6, attack_damageMore = 0.81, }, + [3] = { skill_manaCostBase = 6, attack_damageMore = 0.82, }, + [4] = { skill_manaCostBase = 7, attack_damageMore = 0.83, }, + [5] = { skill_manaCostBase = 7, attack_damageMore = 0.84, }, + [6] = { skill_manaCostBase = 7, attack_damageMore = 0.85, }, + [7] = { skill_manaCostBase = 7, attack_damageMore = 0.86, }, + [8] = { skill_manaCostBase = 8, attack_damageMore = 0.87, }, + [9] = { skill_manaCostBase = 8, attack_damageMore = 0.88, }, + [10] = { skill_manaCostBase = 8, attack_damageMore = 0.89, }, + [11] = { skill_manaCostBase = 8, attack_damageMore = 0.9, }, + [12] = { skill_manaCostBase = 8, attack_damageMore = 0.91, }, + [13] = { skill_manaCostBase = 9, attack_damageMore = 0.92, }, + [14] = { skill_manaCostBase = 9, attack_damageMore = 0.93, }, + [15] = { skill_manaCostBase = 9, attack_damageMore = 0.94, }, + [16] = { skill_manaCostBase = 9, attack_damageMore = 0.95, }, + [17] = { skill_manaCostBase = 9, attack_damageMore = 0.96, }, + [18] = { skill_manaCostBase = 10, attack_damageMore = 0.97, }, + [19] = { skill_manaCostBase = 10, attack_damageMore = 0.98, }, + [20] = { skill_manaCostBase = 10, attack_damageMore = 0.99, }, + [21] = { skill_manaCostBase = 10, attack_damageMore = 1, }, + [22] = { skill_manaCostBase = 10, attack_damageMore = 1.01, }, + [23] = { skill_manaCostBase = 11, attack_damageMore = 1.02, }, + [24] = { skill_manaCostBase = 11, attack_damageMore = 1.03, }, + [25] = { skill_manaCostBase = 11, attack_damageMore = 1.04, }, + [26] = { skill_manaCostBase = 11, attack_damageMore = 1.05, }, + [27] = { skill_manaCostBase = 11, attack_damageMore = 1.06, }, + [28] = { skill_manaCostBase = 12, attack_damageMore = 1.07, }, + [29] = { skill_manaCostBase = 12, attack_damageMore = 1.08, }, + [30] = { skill_manaCostBase = 12, attack_damageMore = 1.09, }, + } +} +gems["Siege Ballista"] = { + attack = true, + totem = true, + bow = true, + projectile = true, + duration = true, + base = { + skill_durationBase = 8, + pierceChance = 100, + attackSpeedMore = 0.5, + }, + quality = { + totemPlacementSpeedInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 8, attack_damageMore = 1.4, }, + [2] = { skill_manaCostBase = 8, attack_damageMore = 1.416, }, + [3] = { skill_manaCostBase = 8, attack_damageMore = 1.432, }, + [4] = { skill_manaCostBase = 9, attack_damageMore = 1.448, }, + [5] = { skill_manaCostBase = 9, attack_damageMore = 1.464, }, + [6] = { skill_manaCostBase = 9, attack_damageMore = 1.48, }, + [7] = { skill_manaCostBase = 9, attack_damageMore = 1.496, }, + [8] = { skill_manaCostBase = 9, attack_damageMore = 1.512, }, + [9] = { skill_manaCostBase = 9, attack_damageMore = 1.528, }, + [10] = { skill_manaCostBase = 10, attack_damageMore = 1.544, }, + [11] = { skill_manaCostBase = 10, attack_damageMore = 1.56, }, + [12] = { skill_manaCostBase = 10, attack_damageMore = 1.576, }, + [13] = { skill_manaCostBase = 10, attack_damageMore = 1.592, }, + [14] = { skill_manaCostBase = 10, attack_damageMore = 1.608, }, + [15] = { skill_manaCostBase = 11, attack_damageMore = 1.624, }, + [16] = { skill_manaCostBase = 11, attack_damageMore = 1.64, }, + [17] = { skill_manaCostBase = 12, attack_damageMore = 1.656, }, + [18] = { skill_manaCostBase = 12, attack_damageMore = 1.672, }, + [19] = { skill_manaCostBase = 12, attack_damageMore = 1.688, }, + [20] = { skill_manaCostBase = 13, attack_damageMore = 1.704, }, + [21] = { skill_manaCostBase = 13, attack_damageMore = 1.72, }, + [22] = { skill_manaCostBase = 13, attack_damageMore = 1.736, }, + [23] = { skill_manaCostBase = 14, attack_damageMore = 1.752, }, + [24] = { skill_manaCostBase = 14, attack_damageMore = 1.768, }, + [25] = { skill_manaCostBase = 14, attack_damageMore = 1.784, }, + [26] = { skill_manaCostBase = 14, attack_damageMore = 1.8, }, + [27] = { skill_manaCostBase = 14, attack_damageMore = 1.816, }, + [28] = { skill_manaCostBase = 14, attack_damageMore = 1.832, }, + [29] = { skill_manaCostBase = 15, attack_damageMore = 1.848, }, + [30] = { skill_manaCostBase = 15, attack_damageMore = 1.864, }, + } +} +gems["Smoke Mine"] = { + unsupported = true, +} +gems["Spectral Throw"] = { + attack = true, + projectile = true, + base = { + pierceChance = 100, + }, + quality = { + attackSpeedInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 7, attack_damageMore = 0.54, }, + [2] = { skill_manaCostBase = 7, attack_damageMore = 0.56, }, + [3] = { skill_manaCostBase = 7, attack_damageMore = 0.579, }, + [4] = { skill_manaCostBase = 7, attack_damageMore = 0.598, }, + [5] = { skill_manaCostBase = 7, attack_damageMore = 0.617, }, + [6] = { skill_manaCostBase = 7, attack_damageMore = 0.636, }, + [7] = { skill_manaCostBase = 7, attack_damageMore = 0.656, }, + [8] = { skill_manaCostBase = 7, attack_damageMore = 0.675, }, + [9] = { skill_manaCostBase = 7, attack_damageMore = 0.694, }, + [10] = { skill_manaCostBase = 7, attack_damageMore = 0.713, }, + [11] = { skill_manaCostBase = 8, attack_damageMore = 0.732, }, + [12] = { skill_manaCostBase = 8, attack_damageMore = 0.752, }, + [13] = { skill_manaCostBase = 8, attack_damageMore = 0.771, }, + [14] = { skill_manaCostBase = 8, attack_damageMore = 0.79, }, + [15] = { skill_manaCostBase = 8, attack_damageMore = 0.809, }, + [16] = { skill_manaCostBase = 9, attack_damageMore = 0.828, }, + [17] = { skill_manaCostBase = 9, attack_damageMore = 0.848, }, + [18] = { skill_manaCostBase = 9, attack_damageMore = 0.867, }, + [19] = { skill_manaCostBase = 9, attack_damageMore = 0.886, }, + [20] = { skill_manaCostBase = 9, attack_damageMore = 0.905, }, + [21] = { skill_manaCostBase = 10, attack_damageMore = 0.924, }, + [22] = { skill_manaCostBase = 10, attack_damageMore = 0.944, }, + [23] = { skill_manaCostBase = 10, attack_damageMore = 0.963, }, + [24] = { skill_manaCostBase = 10, attack_damageMore = 0.982, }, + [25] = { skill_manaCostBase = 10, attack_damageMore = 1, }, + [26] = { skill_manaCostBase = 10, attack_damageMore = 1.02, }, + [27] = { skill_manaCostBase = 10, attack_damageMore = 1.039, }, + [28] = { skill_manaCostBase = 10, attack_damageMore = 1.058, }, + [29] = { skill_manaCostBase = 10, attack_damageMore = 1.077, }, + [30] = { skill_manaCostBase = 10, attack_damageMore = 1.096, }, + } +} +gems["Split Arrow"] = { + attack = true, + bow = true, + projectile = true, + base = { + }, + quality = { + attackSpeedInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 6, attack_damageMore = 0.9, }, + [2] = { skill_manaCostBase = 6, attack_damageMore = 0.91, }, + [3] = { skill_manaCostBase = 6, attack_damageMore = 0.92, }, + [4] = { skill_manaCostBase = 7, attack_damageMore = 0.93, }, + [5] = { skill_manaCostBase = 7, attack_damageMore = 0.94, }, + [6] = { skill_manaCostBase = 7, attack_damageMore = 0.95, }, + [7] = { skill_manaCostBase = 7, attack_damageMore = 0.96, }, + [8] = { skill_manaCostBase = 8, attack_damageMore = 0.97, }, + [9] = { skill_manaCostBase = 8, attack_damageMore = 0.98, }, + [10] = { skill_manaCostBase = 8, attack_damageMore = 0.99, }, + [11] = { skill_manaCostBase = 8, attack_damageMore = 1, }, + [12] = { skill_manaCostBase = 8, attack_damageMore = 1.01, }, + [13] = { skill_manaCostBase = 9, attack_damageMore = 1.02, }, + [14] = { skill_manaCostBase = 9, attack_damageMore = 1.03, }, + [15] = { skill_manaCostBase = 9, attack_damageMore = 1.04, }, + [16] = { skill_manaCostBase = 9, attack_damageMore = 1.05, }, + [17] = { skill_manaCostBase = 9, attack_damageMore = 1.06, }, + [18] = { skill_manaCostBase = 10, attack_damageMore = 1.07, }, + [19] = { skill_manaCostBase = 10, attack_damageMore = 1.08, }, + [20] = { skill_manaCostBase = 10, attack_damageMore = 1.09, }, + [21] = { skill_manaCostBase = 10, attack_damageMore = 1.1, }, + [22] = { skill_manaCostBase = 10, attack_damageMore = 1.11, }, + [23] = { skill_manaCostBase = 11, attack_damageMore = 1.12, }, + [24] = { skill_manaCostBase = 11, attack_damageMore = 1.13, }, + [25] = { skill_manaCostBase = 11, attack_damageMore = 1.14, }, + [26] = { skill_manaCostBase = 11, attack_damageMore = 1.15, }, + [27] = { skill_manaCostBase = 11, attack_damageMore = 1.16, }, + [28] = { skill_manaCostBase = 12, attack_damageMore = 1.17, }, + [29] = { skill_manaCostBase = 12, attack_damageMore = 1.18, }, + [30] = { skill_manaCostBase = 12, attack_damageMore = 1.19, }, + } +} +gems["Summon Ice Golem"] = { + spell = true, + minion = true, + golem = true, + cold = true, + base = { + skill_castTime = 1, + }, + quality = { + minionLifeInc = 1, + minion_damageInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 30, minionLifeInc = 30, buff_critChanceInc = 20, buff_accuracyInc = 20, }, + [2] = { skill_manaCostBase = 32, minionLifeInc = 32, buff_critChanceInc = 21, buff_accuracyInc = 21, }, + [3] = { skill_manaCostBase = 34, minionLifeInc = 34, buff_critChanceInc = 21, buff_accuracyInc = 21, }, + [4] = { skill_manaCostBase = 36, minionLifeInc = 36, buff_critChanceInc = 22, buff_accuracyInc = 22, }, + [5] = { skill_manaCostBase = 38, minionLifeInc = 38, buff_critChanceInc = 22, buff_accuracyInc = 22, }, + [6] = { skill_manaCostBase = 40, minionLifeInc = 40, buff_critChanceInc = 23, buff_accuracyInc = 23, }, + [7] = { skill_manaCostBase = 42, minionLifeInc = 42, buff_critChanceInc = 23, buff_accuracyInc = 23, }, + [8] = { skill_manaCostBase = 44, minionLifeInc = 44, buff_critChanceInc = 24, buff_accuracyInc = 24, }, + [9] = { skill_manaCostBase = 44, minionLifeInc = 46, buff_critChanceInc = 24, buff_accuracyInc = 24, }, + [10] = { skill_manaCostBase = 46, minionLifeInc = 48, buff_critChanceInc = 25, buff_accuracyInc = 25, }, + [11] = { skill_manaCostBase = 48, minionLifeInc = 50, buff_critChanceInc = 25, buff_accuracyInc = 25, }, + [12] = { skill_manaCostBase = 48, minionLifeInc = 52, buff_critChanceInc = 26, buff_accuracyInc = 26, }, + [13] = { skill_manaCostBase = 50, minionLifeInc = 54, buff_critChanceInc = 26, buff_accuracyInc = 26, }, + [14] = { skill_manaCostBase = 50, minionLifeInc = 56, buff_critChanceInc = 27, buff_accuracyInc = 27, }, + [15] = { skill_manaCostBase = 52, minionLifeInc = 58, buff_critChanceInc = 27, buff_accuracyInc = 27, }, + [16] = { skill_manaCostBase = 52, minionLifeInc = 60, buff_critChanceInc = 28, buff_accuracyInc = 28, }, + [17] = { skill_manaCostBase = 52, minionLifeInc = 62, buff_critChanceInc = 28, buff_accuracyInc = 28, }, + [18] = { skill_manaCostBase = 52, minionLifeInc = 64, buff_critChanceInc = 29, buff_accuracyInc = 29, }, + [19] = { skill_manaCostBase = 54, minionLifeInc = 66, buff_critChanceInc = 29, buff_accuracyInc = 29, }, + [20] = { skill_manaCostBase = 54, minionLifeInc = 68, buff_critChanceInc = 30, buff_accuracyInc = 30, }, + [21] = { skill_manaCostBase = 56, minionLifeInc = 70, buff_critChanceInc = 30, buff_accuracyInc = 30, }, + [22] = { skill_manaCostBase = 56, minionLifeInc = 72, buff_critChanceInc = 31, buff_accuracyInc = 31, }, + [23] = { skill_manaCostBase = 58, minionLifeInc = 74, buff_critChanceInc = 31, buff_accuracyInc = 31, }, + [24] = { skill_manaCostBase = 58, minionLifeInc = 76, buff_critChanceInc = 32, buff_accuracyInc = 32, }, + [25] = { skill_manaCostBase = 60, minionLifeInc = 78, buff_critChanceInc = 32, buff_accuracyInc = 32, }, + [26] = { skill_manaCostBase = 60, minionLifeInc = 80, buff_critChanceInc = 33, buff_accuracyInc = 33, }, + [27] = { skill_manaCostBase = 60, minionLifeInc = 82, buff_critChanceInc = 33, buff_accuracyInc = 33, }, + [28] = { skill_manaCostBase = 60, minionLifeInc = 84, buff_critChanceInc = 34, buff_accuracyInc = 34, }, + [29] = { skill_manaCostBase = 62, minionLifeInc = 86, buff_critChanceInc = 34, buff_accuracyInc = 34, }, + [30] = { skill_manaCostBase = 62, minionLifeInc = 88, buff_critChanceInc = 35, buff_accuracyInc = 35, }, + } +} +gems["Temporal Chains"] = { + unsupported = true, +} +gems["Tornado Shot"] = { + attack = true, + bow = true, + projectile = true, + base = { + }, + quality = { + projectile_damageInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 8, attack_damageMore = 0.9, }, + [2] = { skill_manaCostBase = 8, attack_damageMore = 0.91, }, + [3] = { skill_manaCostBase = 8, attack_damageMore = 0.92, }, + [4] = { skill_manaCostBase = 8, attack_damageMore = 0.93, }, + [5] = { skill_manaCostBase = 9, attack_damageMore = 0.94, }, + [6] = { skill_manaCostBase = 9, attack_damageMore = 0.95, }, + [7] = { skill_manaCostBase = 9, attack_damageMore = 0.96, }, + [8] = { skill_manaCostBase = 9, attack_damageMore = 0.97, }, + [9] = { skill_manaCostBase = 9, attack_damageMore = 0.98, }, + [10] = { skill_manaCostBase = 9, attack_damageMore = 0.99, }, + [11] = { skill_manaCostBase = 9, attack_damageMore = 1, }, + [12] = { skill_manaCostBase = 10, attack_damageMore = 1.01, }, + [13] = { skill_manaCostBase = 10, attack_damageMore = 1.02, }, + [14] = { skill_manaCostBase = 10, attack_damageMore = 1.03, }, + [15] = { skill_manaCostBase = 10, attack_damageMore = 1.04, }, + [16] = { skill_manaCostBase = 10, attack_damageMore = 1.05, }, + [17] = { skill_manaCostBase = 10, attack_damageMore = 1.06, }, + [18] = { skill_manaCostBase = 10, attack_damageMore = 1.07, }, + [19] = { skill_manaCostBase = 10, attack_damageMore = 1.08, }, + [20] = { skill_manaCostBase = 10, attack_damageMore = 1.09, }, + [21] = { skill_manaCostBase = 10, attack_damageMore = 1.1, }, + [22] = { skill_manaCostBase = 10, attack_damageMore = 1.11, }, + [23] = { skill_manaCostBase = 11, attack_damageMore = 1.12, }, + [24] = { skill_manaCostBase = 11, attack_damageMore = 1.13, }, + [25] = { skill_manaCostBase = 11, attack_damageMore = 1.14, }, + [26] = { skill_manaCostBase = 11, attack_damageMore = 1.15, }, + [27] = { skill_manaCostBase = 11, attack_damageMore = 1.16, }, + [28] = { skill_manaCostBase = 12, attack_damageMore = 1.17, }, + [29] = { skill_manaCostBase = 12, attack_damageMore = 1.18, }, + [30] = { skill_manaCostBase = 12, attack_damageMore = 1.19, }, + } +} +gems["Viper Strike"] = { + attack = true, + melee = true, + duration = true, + chaos = true, + base = { + skill_manaCostBase = 5, + physicalConvertTochaos = 25, + poisonChance = 100, + poison_durationMore = 4, + }, + quality = { + attackSpeedInc = 0.5 + }, + levels = { + [1] = { attack_damageMore = 1.3, }, + [2] = { attack_damageMore = 1.316, }, + [3] = { attack_damageMore = 1.332, }, + [4] = { attack_damageMore = 1.348, }, + [5] = { attack_damageMore = 1.364, }, + [6] = { attack_damageMore = 1.38, }, + [7] = { attack_damageMore = 1.396, }, + [8] = { attack_damageMore = 1.412, }, + [9] = { attack_damageMore = 1.428, }, + [10] = { attack_damageMore = 1.444, }, + [11] = { attack_damageMore = 1.46, }, + [12] = { attack_damageMore = 1.476, }, + [13] = { attack_damageMore = 1.492, }, + [14] = { attack_damageMore = 1.508, }, + [15] = { attack_damageMore = 1.524, }, + [16] = { attack_damageMore = 1.54, }, + [17] = { attack_damageMore = 1.556, }, + [18] = { attack_damageMore = 1.572, }, + [19] = { attack_damageMore = 1.588, }, + [20] = { attack_damageMore = 1.604, }, + [21] = { attack_damageMore = 1.62, }, + [22] = { attack_damageMore = 1.636, }, + [23] = { attack_damageMore = 1.652, }, + [24] = { attack_damageMore = 1.668, }, + [25] = { attack_damageMore = 1.684, }, + [26] = { attack_damageMore = 1.7, }, + [27] = { attack_damageMore = 1.716, }, + [28] = { attack_damageMore = 1.732, }, + [29] = { attack_damageMore = 1.748, }, + [30] = { attack_damageMore = 1.764, }, + } +} +gems["Whirling Blades"] = { + unsupported = true, +} +gems["Wild Strike"] = { + attack = true, + melee = true, + projectile = true, + aoe = true, + lightning = true, + cold = true, + fire = true, + parts = { + { + name = "Fire hit", + melee = true, + projectile = false, + aoe = false, + }, + { + name = "Fire explosion", + melee = false, + projectile = false, + aoe = true, + }, + { + name = "Lightning hit", + melee = true, + projectile = false, + aoe = false, + }, + { + name = "Lightning bolt", + melee = false, + projectile = false, + aoe = false, + }, + { + name = "Cold hit", + melee = true, + projectile = false, + aoe = false, + }, + { + name = "Icy wave", + melee = false, + projectile = true, + aoe = false, + }, + }, + base = { + skill_manaCostBase = 6, + part1_physicalConvertTofire = 60, + part2_physicalConvertTofire = 60, + part3_physicalConvertTolightning = 60, + part4_physicalConvertTolightning = 60, + part5_physicalGainAscold = 60, + part6_physicalGainAscold = 60, + }, + quality = { + elemInc = 1, + }, + levels = { + [1] = { attack_damageMore = 1.2, }, + [2] = { attack_damageMore = 1.214, }, + [3] = { attack_damageMore = 1.228, }, + [4] = { attack_damageMore = 1.242, }, + [5] = { attack_damageMore = 1.256, }, + [6] = { attack_damageMore = 1.27, }, + [7] = { attack_damageMore = 1.284, }, + [8] = { attack_damageMore = 1.298, }, + [9] = { attack_damageMore = 1.312, }, + [10] = { attack_damageMore = 1.326, }, + [11] = { attack_damageMore = 1.34, }, + [12] = { attack_damageMore = 1.354, }, + [13] = { attack_damageMore = 1.368, }, + [14] = { attack_damageMore = 1.382, }, + [15] = { attack_damageMore = 1.396, }, + [16] = { attack_damageMore = 1.41, }, + [17] = { attack_damageMore = 1.424, }, + [18] = { attack_damageMore = 1.438, }, + [19] = { attack_damageMore = 1.452, }, + [20] = { attack_damageMore = 1.466, }, + [21] = { attack_damageMore = 1.48, }, + [22] = { attack_damageMore = 1.494, }, + [23] = { attack_damageMore = 1.508, }, + [24] = { attack_damageMore = 1.522, }, + [25] = { attack_damageMore = 1.536, }, + [26] = { attack_damageMore = 1.55, }, + [27] = { attack_damageMore = 1.564, }, + [28] = { attack_damageMore = 1.578, }, + [29] = { attack_damageMore = 1.592, }, + [30] = { attack_damageMore = 1.606, }, + } +} + + diff --git a/Gems/act_int.lua b/Gems/act_int.lua new file mode 100644 index 00000000..37751fdb --- /dev/null +++ b/Gems/act_int.lua @@ -0,0 +1,1709 @@ +local gems = ... + +gems["Arc"] = { + spell = true, + lightning = true, + base = { + skill_castTime = 0.8, + skill_damageEff = 0.7, + skill_critChanceBase = 5, + shockChance = 10, + }, + quality = { + shockChance = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 9, skill_lightningMin = 2, skill_lightningMax = 35, }, + [2] = { skill_manaCostBase = 10, skill_lightningMin = 2, skill_lightningMax = 44, }, + [3] = { skill_manaCostBase = 11, skill_lightningMin = 3, skill_lightningMax = 58, }, + [4] = { skill_manaCostBase = 12, skill_lightningMin = 4, skill_lightningMax = 76, }, + [5] = { skill_manaCostBase = 13, skill_lightningMin = 5, skill_lightningMax = 97, }, + [6] = { skill_manaCostBase = 14, skill_lightningMin = 6, skill_lightningMax = 123, }, + [7] = { skill_manaCostBase = 16, skill_lightningMin = 8, skill_lightningMax = 154, }, + [8] = { skill_manaCostBase = 16, skill_lightningMin = 10, skill_lightningMax = 182, }, + [9] = { skill_manaCostBase = 17, skill_lightningMin = 11, skill_lightningMax = 214, }, + [10] = { skill_manaCostBase = 18, skill_lightningMin = 13, skill_lightningMax = 250, }, + [11] = { skill_manaCostBase = 19, skill_lightningMin = 15, skill_lightningMax = 292, }, + [12] = { skill_manaCostBase = 20, skill_lightningMin = 18, skill_lightningMax = 340, }, + [13] = { skill_manaCostBase = 21, skill_lightningMin = 21, skill_lightningMax = 395, }, + [14] = { skill_manaCostBase = 22, skill_lightningMin = 24, skill_lightningMax = 458, }, + [15] = { skill_manaCostBase = 23, skill_lightningMin = 28, skill_lightningMax = 529, }, + [16] = { skill_manaCostBase = 24, skill_lightningMin = 32, skill_lightningMax = 610, }, + [17] = { skill_manaCostBase = 24, skill_lightningMin = 35, skill_lightningMax = 671, }, + [18] = { skill_manaCostBase = 25, skill_lightningMin = 39, skill_lightningMax = 736, }, + [19] = { skill_manaCostBase = 25, skill_lightningMin = 43, skill_lightningMax = 808, }, + [20] = { skill_manaCostBase = 26, skill_lightningMin = 47, skill_lightningMax = 886, }, + [21] = { skill_manaCostBase = 26, skill_lightningMin = 51, skill_lightningMax = 971, }, + [22] = { skill_manaCostBase = 26, skill_lightningMin = 56, skill_lightningMax = 1064, }, + [23] = { skill_manaCostBase = 27, skill_lightningMin = 61, skill_lightningMax = 1164, }, + [24] = { skill_manaCostBase = 28, skill_lightningMin = 67, skill_lightningMax = 1274, }, + [25] = { skill_manaCostBase = 29, skill_lightningMin = 73, skill_lightningMax = 1393, }, + [26] = { skill_manaCostBase = 30, skill_lightningMin = 80, skill_lightningMax = 1523, }, + [27] = { skill_manaCostBase = 30, skill_lightningMin = 88, skill_lightningMax = 1663, }, + [28] = { skill_manaCostBase = 30, skill_lightningMin = 96, skill_lightningMax = 1816, }, + [29] = { skill_manaCostBase = 31, skill_lightningMin = 104, skill_lightningMax = 1983, }, + [30] = { skill_manaCostBase = 32, skill_lightningMin = 114, skill_lightningMax = 2163, }, + } +} +gems["Arctic Breath"] = { + spell = true, + aoe = true, + projectile = true, + duration = true, + cold = true, + base = { + skill_castTime = 0.8, + skill_damageEff = 1, + skill_critChanceBase = 5, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 11, skill_durationBase = 0.88, skill_coldMin = 46, skill_coldMax = 70, }, + [2] = { skill_manaCostBase = 11, skill_durationBase = 0.94, skill_coldMin = 56, skill_coldMax = 84, }, + [3] = { skill_manaCostBase = 12, skill_durationBase = 0.99, skill_coldMin = 67, skill_coldMax = 100, }, + [4] = { skill_manaCostBase = 13, skill_durationBase = 1.05, skill_coldMin = 80, skill_coldMax = 120, }, + [5] = { skill_manaCostBase = 14, skill_durationBase = 1.1, skill_coldMin = 95, skill_coldMax = 142, }, + [6] = { skill_manaCostBase = 14, skill_durationBase = 1.16, skill_coldMin = 106, skill_coldMax = 159, }, + [7] = { skill_manaCostBase = 15, skill_durationBase = 1.21, skill_coldMin = 118, skill_coldMax = 177, }, + [8] = { skill_manaCostBase = 15, skill_durationBase = 1.27, skill_coldMin = 132, skill_coldMax = 198, }, + [9] = { skill_manaCostBase = 16, skill_durationBase = 1.32, skill_coldMin = 147, skill_coldMax = 220, }, + [10] = { skill_manaCostBase = 16, skill_durationBase = 1.35, skill_coldMin = 164, skill_coldMax = 245, }, + [11] = { skill_manaCostBase = 16, skill_durationBase = 1.38, skill_coldMin = 182, skill_coldMax = 273, }, + [12] = { skill_manaCostBase = 17, skill_durationBase = 1.4, skill_coldMin = 202, skill_coldMax = 303, }, + [13] = { skill_manaCostBase = 17, skill_durationBase = 1.43, skill_coldMin = 224, skill_coldMax = 336, }, + [14] = { skill_manaCostBase = 18, skill_durationBase = 1.46, skill_coldMin = 248, skill_coldMax = 372, }, + [15] = { skill_manaCostBase = 18, skill_durationBase = 1.49, skill_coldMin = 274, skill_coldMax = 412, }, + [16] = { skill_manaCostBase = 19, skill_durationBase = 1.51, skill_coldMin = 304, skill_coldMax = 455, }, + [17] = { skill_manaCostBase = 19, skill_durationBase = 1.54, skill_coldMin = 336, skill_coldMax = 503, }, + [18] = { skill_manaCostBase = 20, skill_durationBase = 1.57, skill_coldMin = 371, skill_coldMax = 556, }, + [19] = { skill_manaCostBase = 20, skill_durationBase = 1.6, skill_coldMin = 409, skill_coldMax = 614, }, + [20] = { skill_manaCostBase = 21, skill_durationBase = 1.65, skill_coldMin = 451, skill_coldMax = 677, }, + [21] = { skill_manaCostBase = 21, skill_durationBase = 1.71, skill_coldMin = 497, skill_coldMax = 746, }, + [22] = { skill_manaCostBase = 22, skill_durationBase = 1.76, skill_coldMin = 548, skill_coldMax = 822, }, + [23] = { skill_manaCostBase = 22, skill_durationBase = 1.82, skill_coldMin = 603, skill_coldMax = 905, }, + [24] = { skill_manaCostBase = 23, skill_durationBase = 1.87, skill_coldMin = 664, skill_coldMax = 996, }, + [25] = { skill_manaCostBase = 23, skill_durationBase = 1.93, skill_coldMin = 730, skill_coldMax = 1096, }, + [26] = { skill_manaCostBase = 24, skill_durationBase = 1.98, skill_coldMin = 803, skill_coldMax = 1204, }, + [27] = { skill_manaCostBase = 24, skill_durationBase = 2.04, skill_coldMin = 882, skill_coldMax = 1323, }, + [28] = { skill_manaCostBase = 25, skill_durationBase = 2.09, skill_coldMin = 969, skill_coldMax = 1453, }, + [29] = { skill_manaCostBase = 25, skill_durationBase = 2.15, skill_coldMin = 1064, skill_coldMax = 1596, }, + [30] = { skill_manaCostBase = 26, skill_durationBase = 2.2, skill_coldMin = 1167, skill_coldMax = 1751, }, + } +} +gems["Assassin's Mark"] = { + unsupported = true, +} +gems["Ball Lightning"] = { + spell = true, + aoe = true, + projectile = true, + lightning = true, + parts = { + { + aoe = false, + }, + }, + base = { + skill_castTime = 0.8, + skill_damageEff = 0.2, + skill_critChanceBase = 5, + }, + quality = { + lightningInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 14, skill_lightningMin = 2, skill_lightningMax = 32, }, + [2] = { skill_manaCostBase = 15, skill_lightningMin = 2, skill_lightningMax = 38, }, + [3] = { skill_manaCostBase = 16, skill_lightningMin = 2, skill_lightningMax = 45, }, + [4] = { skill_manaCostBase = 17, skill_lightningMin = 3, skill_lightningMax = 53, }, + [5] = { skill_manaCostBase = 18, skill_lightningMin = 3, skill_lightningMax = 62, }, + [6] = { skill_manaCostBase = 19, skill_lightningMin = 4, skill_lightningMax = 69, }, + [7] = { skill_manaCostBase = 20, skill_lightningMin = 4, skill_lightningMax = 76, }, + [8] = { skill_manaCostBase = 21, skill_lightningMin = 4, skill_lightningMax = 84, }, + [9] = { skill_manaCostBase = 22, skill_lightningMin = 5, skill_lightningMax = 93, }, + [10] = { skill_manaCostBase = 23, skill_lightningMin = 5, skill_lightningMax = 103, }, + [11] = { skill_manaCostBase = 24, skill_lightningMin = 6, skill_lightningMax = 113, }, + [12] = { skill_manaCostBase = 25, skill_lightningMin = 7, skill_lightningMax = 124, }, + [13] = { skill_manaCostBase = 25, skill_lightningMin = 7, skill_lightningMax = 137, }, + [14] = { skill_manaCostBase = 25, skill_lightningMin = 8, skill_lightningMax = 150, }, + [15] = { skill_manaCostBase = 26, skill_lightningMin = 9, skill_lightningMax = 165, }, + [16] = { skill_manaCostBase = 26, skill_lightningMin = 10, skill_lightningMax = 181, }, + [17] = { skill_manaCostBase = 26, skill_lightningMin = 10, skill_lightningMax = 199, }, + [18] = { skill_manaCostBase = 26, skill_lightningMin = 11, skill_lightningMax = 217, }, + [19] = { skill_manaCostBase = 27, skill_lightningMin = 13, skill_lightningMax = 238, }, + [20] = { skill_manaCostBase = 27, skill_lightningMin = 14, skill_lightningMax = 260, }, + [21] = { skill_manaCostBase = 28, skill_lightningMin = 15, skill_lightningMax = 285, }, + [22] = { skill_manaCostBase = 28, skill_lightningMin = 16, skill_lightningMax = 311, }, + [23] = { skill_manaCostBase = 29, skill_lightningMin = 18, skill_lightningMax = 340, }, + [24] = { skill_manaCostBase = 29, skill_lightningMin = 20, skill_lightningMax = 371, }, + [25] = { skill_manaCostBase = 30, skill_lightningMin = 21, skill_lightningMax = 404, }, + [26] = { skill_manaCostBase = 30, skill_lightningMin = 23, skill_lightningMax = 441, }, + [27] = { skill_manaCostBase = 30, skill_lightningMin = 25, skill_lightningMax = 480, }, + [28] = { skill_manaCostBase = 30, skill_lightningMin = 28, skill_lightningMax = 523, }, + [29] = { skill_manaCostBase = 31, skill_lightningMin = 30, skill_lightningMax = 570, }, + [30] = { skill_manaCostBase = 31, skill_lightningMin = 33, skill_lightningMax = 620, }, + } +} +gems["Bone Offering"] = { + unsupported = true, +} +gems["Clarity"] = { + aura = true, + spell = true, + aoe = true, + base = { + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { skill_manaReservedBase = 34, auraRadiusInc = 0, manaRegenBase = 2.9, }, + [2] = { skill_manaReservedBase = 48, auraRadiusInc = 3, manaRegenBase = 4, }, + [3] = { skill_manaReservedBase = 61, auraRadiusInc = 6, manaRegenBase = 5.1, }, + [4] = { skill_manaReservedBase = 76, auraRadiusInc = 9, manaRegenBase = 6.1, }, + [5] = { skill_manaReservedBase = 89, auraRadiusInc = 12, manaRegenBase = 7, }, + [6] = { skill_manaReservedBase = 102, auraRadiusInc = 15, manaRegenBase = 7.9, }, + [7] = { skill_manaReservedBase = 115, auraRadiusInc = 18, manaRegenBase = 8.8, }, + [8] = { skill_manaReservedBase = 129, auraRadiusInc = 21, manaRegenBase = 9.6, }, + [9] = { skill_manaReservedBase = 141, auraRadiusInc = 23, manaRegenBase = 10.3, }, + [10] = { skill_manaReservedBase = 154, auraRadiusInc = 25, manaRegenBase = 11.1, }, + [11] = { skill_manaReservedBase = 166, auraRadiusInc = 27, manaRegenBase = 11.7, }, + [12] = { skill_manaReservedBase = 178, auraRadiusInc = 29, manaRegenBase = 12.4, }, + [13] = { skill_manaReservedBase = 190, auraRadiusInc = 31, manaRegenBase = 13, }, + [14] = { skill_manaReservedBase = 203, auraRadiusInc = 33, manaRegenBase = 13.7, }, + [15] = { skill_manaReservedBase = 214, auraRadiusInc = 35, manaRegenBase = 14.2, }, + [16] = { skill_manaReservedBase = 227, auraRadiusInc = 36, manaRegenBase = 14.8, }, + [17] = { skill_manaReservedBase = 239, auraRadiusInc = 37, manaRegenBase = 15.4, }, + [18] = { skill_manaReservedBase = 251, auraRadiusInc = 38, manaRegenBase = 16, }, + [19] = { skill_manaReservedBase = 265, auraRadiusInc = 39, manaRegenBase = 16.6, }, + [20] = { skill_manaReservedBase = 279, auraRadiusInc = 40, manaRegenBase = 17.2, }, + [21] = { skill_manaReservedBase = 293, auraRadiusInc = 41, manaRegenBase = 17.8, }, + [22] = { skill_manaReservedBase = 303, auraRadiusInc = 42, manaRegenBase = 18.4, }, + [23] = { skill_manaReservedBase = 313, auraRadiusInc = 43, manaRegenBase = 19, }, + [24] = { skill_manaReservedBase = 323, auraRadiusInc = 44, manaRegenBase = 19.6, }, + [25] = { skill_manaReservedBase = 333, auraRadiusInc = 45, manaRegenBase = 20.2, }, + [26] = { skill_manaReservedBase = 343, auraRadiusInc = 46, manaRegenBase = 20.8, }, + [27] = { skill_manaReservedBase = 353, auraRadiusInc = 47, manaRegenBase = 21.4, }, + [28] = { skill_manaReservedBase = 363, auraRadiusInc = 48, manaRegenBase = 22, }, + [29] = { skill_manaReservedBase = 373, auraRadiusInc = 49, manaRegenBase = 22.6, }, + [30] = { skill_manaReservedBase = 383, auraRadiusInc = 50, manaRegenBase = 23.2, }, + } +} +gems["Cold Snap"] = { + spell = true, + aoe = true, + cold = true, + base = { + skill_castTime = 0.85, + skill_damageEff = 1.2, + skill_critChanceBase = 5, + freezeChance = 30, + freeze_durationInc = 30, + chill_durationInc = 110, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 11, skill_coldMin = 9, skill_coldMax = 13, }, + [2] = { skill_manaCostBase = 12, skill_coldMin = 11, skill_coldMax = 16, }, + [3] = { skill_manaCostBase = 13, skill_coldMin = 14, skill_coldMax = 21, }, + [4] = { skill_manaCostBase = 14, skill_coldMin = 18, skill_coldMax = 27, }, + [5] = { skill_manaCostBase = 15, skill_coldMin = 25, skill_coldMax = 37, }, + [6] = { skill_manaCostBase = 16, skill_coldMin = 32, skill_coldMax = 49, }, + [7] = { skill_manaCostBase = 17, skill_coldMin = 42, skill_coldMax = 63, }, + [8] = { skill_manaCostBase = 18, skill_coldMin = 54, skill_coldMax = 81, }, + [9] = { skill_manaCostBase = 19, skill_coldMin = 68, skill_coldMax = 102, }, + [10] = { skill_manaCostBase = 20, skill_coldMin = 85, skill_coldMax = 128, }, + [11] = { skill_manaCostBase = 21, skill_coldMin = 106, skill_coldMax = 159, }, + [12] = { skill_manaCostBase = 22, skill_coldMin = 131, skill_coldMax = 196, }, + [13] = { skill_manaCostBase = 23, skill_coldMin = 160, skill_coldMax = 240, }, + [14] = { skill_manaCostBase = 24, skill_coldMin = 196, skill_coldMax = 294, }, + [15] = { skill_manaCostBase = 25, skill_coldMin = 227, skill_coldMax = 341, }, + [16] = { skill_manaCostBase = 26, skill_coldMin = 263, skill_coldMax = 394, }, + [17] = { skill_manaCostBase = 26, skill_coldMin = 303, skill_coldMax = 455, }, + [18] = { skill_manaCostBase = 27, skill_coldMin = 350, skill_coldMax = 524, }, + [19] = { skill_manaCostBase = 27, skill_coldMin = 402, skill_coldMax = 603, }, + [20] = { skill_manaCostBase = 28, skill_coldMin = 462, skill_coldMax = 693, }, + [21] = { skill_manaCostBase = 28, skill_coldMin = 506, skill_coldMax = 759, }, + [22] = { skill_manaCostBase = 29, skill_coldMin = 554, skill_coldMax = 832, }, + [23] = { skill_manaCostBase = 29, skill_coldMin = 607, skill_coldMax = 910, }, + [24] = { skill_manaCostBase = 30, skill_coldMin = 664, skill_coldMax = 996, }, + [25] = { skill_manaCostBase = 30, skill_coldMin = 726, skill_coldMax = 1089, }, + [26] = { skill_manaCostBase = 30, skill_coldMin = 794, skill_coldMax = 1191, }, + [27] = { skill_manaCostBase = 30, skill_coldMin = 867, skill_coldMax = 1301, }, + [28] = { skill_manaCostBase = 31, skill_coldMin = 947, skill_coldMax = 1420, }, + [29] = { skill_manaCostBase = 31, skill_coldMin = 1033, skill_coldMax = 1550, }, + [30] = { skill_manaCostBase = 32, skill_coldMin = 1127, skill_coldMax = 1691, }, + } +} +gems["Conductivity"] = { + unsupported = true, +} +gems["Contagion"] = { + spell = true, + aoe = true, + duration = true, + chaos = true, + base = { + skill_castTime = 0.85, + skill_dotIsSpell = true, + skill_durationBase = 5, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 11, skill_chaosDotBase = 3.2, }, + [2] = { skill_manaCostBase = 12, skill_chaosDotBase = 3.9, }, + [3] = { skill_manaCostBase = 13, skill_chaosDotBase = 5.2, }, + [4] = { skill_manaCostBase = 14, skill_chaosDotBase = 6.7, }, + [5] = { skill_manaCostBase = 15, skill_chaosDotBase = 9.1, }, + [6] = { skill_manaCostBase = 16, skill_chaosDotBase = 12.1, }, + [7] = { skill_manaCostBase = 17, skill_chaosDotBase = 15.8, }, + [8] = { skill_manaCostBase = 18, skill_chaosDotBase = 20.3, }, + [9] = { skill_manaCostBase = 19, skill_chaosDotBase = 25.9, }, + [10] = { skill_manaCostBase = 20, skill_chaosDotBase = 32.6, }, + [11] = { skill_manaCostBase = 21, skill_chaosDotBase = 40.9, }, + [12] = { skill_manaCostBase = 22, skill_chaosDotBase = 50.9, }, + [13] = { skill_manaCostBase = 23, skill_chaosDotBase = 63, }, + [14] = { skill_manaCostBase = 24, skill_chaosDotBase = 77.6, }, + [15] = { skill_manaCostBase = 25, skill_chaosDotBase = 90.5, }, + [16] = { skill_manaCostBase = 26, skill_chaosDotBase = 105.2, }, + [17] = { skill_manaCostBase = 26, skill_chaosDotBase = 122.2, }, + [18] = { skill_manaCostBase = 27, skill_chaosDotBase = 141.7, }, + [19] = { skill_manaCostBase = 27, skill_chaosDotBase = 163.9, }, + [20] = { skill_manaCostBase = 28, skill_chaosDotBase = 189.4, }, + [21] = { skill_manaCostBase = 28, skill_chaosDotBase = 208.3, }, + [22] = { skill_manaCostBase = 29, skill_chaosDotBase = 229.1, }, + [23] = { skill_manaCostBase = 29, skill_chaosDotBase = 251.8, }, + [24] = { skill_manaCostBase = 30, skill_chaosDotBase = 276.5, }, + [25] = { skill_manaCostBase = 30, skill_chaosDotBase = 303.5, }, + [26] = { skill_manaCostBase = 30, skill_chaosDotBase = 333, }, + [27] = { skill_manaCostBase = 30, skill_chaosDotBase = 365.2, }, + [28] = { skill_manaCostBase = 31, skill_chaosDotBase = 400.4, }, + [29] = { skill_manaCostBase = 31, skill_chaosDotBase = 438.7, }, + [30] = { skill_manaCostBase = 32, skill_chaosDotBase = 480.4, }, + } +} +gems["Conversion Trap"] = { + unsupported = true, +} +gems["Convocation"] = { + unsupported = true, +} +gems["Discharge"] = { + spell = true, + aoe = true, + lightning = true, + cold = true, + fire = true, + base = { + skill_castTime = 1, + skill_critChanceBase = 7, + skill_damageEff = 1.5, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 24, power_skill_lightningMin = 4, power_skill_lightningMax = 77, endurance_skill_fireMin = 29, endurance_skill_fireMax = 43, frenzy_skill_coldMin = 24, frenzy_skill_coldMax = 36, }, + [2] = { skill_manaCostBase = 26, power_skill_lightningMin = 5, power_skill_lightningMax = 92, endurance_skill_fireMin = 34, endurance_skill_fireMax = 51, frenzy_skill_coldMin = 28, frenzy_skill_coldMax = 42, }, + [3] = { skill_manaCostBase = 27, power_skill_lightningMin = 6, power_skill_lightningMax = 108, endurance_skill_fireMin = 40, endurance_skill_fireMax = 60, frenzy_skill_coldMin = 33, frenzy_skill_coldMax = 49, }, + [4] = { skill_manaCostBase = 29, power_skill_lightningMin = 7, power_skill_lightningMax = 126, endurance_skill_fireMin = 47, endurance_skill_fireMax = 71, frenzy_skill_coldMin = 39, frenzy_skill_coldMax = 58, }, + [5] = { skill_manaCostBase = 31, power_skill_lightningMin = 8, power_skill_lightningMax = 147, endurance_skill_fireMin = 55, endurance_skill_fireMax = 83, frenzy_skill_coldMin = 45, frenzy_skill_coldMax = 68, }, + [6] = { skill_manaCostBase = 32, power_skill_lightningMin = 9, power_skill_lightningMax = 163, endurance_skill_fireMin = 61, endurance_skill_fireMax = 91, frenzy_skill_coldMin = 50, frenzy_skill_coldMax = 75, }, + [7] = { skill_manaCostBase = 33, power_skill_lightningMin = 9, power_skill_lightningMax = 180, endurance_skill_fireMin = 67, endurance_skill_fireMax = 101, frenzy_skill_coldMin = 55, frenzy_skill_coldMax = 82, }, + [8] = { skill_manaCostBase = 34, power_skill_lightningMin = 10, power_skill_lightningMax = 198, endurance_skill_fireMin = 74, endurance_skill_fireMax = 111, frenzy_skill_coldMin = 61, frenzy_skill_coldMax = 91, }, + [9] = { skill_manaCostBase = 35, power_skill_lightningMin = 11, power_skill_lightningMax = 218, endurance_skill_fireMin = 82, endurance_skill_fireMax = 122, frenzy_skill_coldMin = 67, frenzy_skill_coldMax = 100, }, + [10] = { skill_manaCostBase = 36, power_skill_lightningMin = 13, power_skill_lightningMax = 240, endurance_skill_fireMin = 90, endurance_skill_fireMax = 135, frenzy_skill_coldMin = 73, frenzy_skill_coldMax = 110, }, + [11] = { skill_manaCostBase = 37, power_skill_lightningMin = 14, power_skill_lightningMax = 263, endurance_skill_fireMin = 99, endurance_skill_fireMax = 148, frenzy_skill_coldMin = 81, frenzy_skill_coldMax = 121, }, + [12] = { skill_manaCostBase = 38, power_skill_lightningMin = 15, power_skill_lightningMax = 289, endurance_skill_fireMin = 108, endurance_skill_fireMax = 162, frenzy_skill_coldMin = 88, frenzy_skill_coldMax = 133, }, + [13] = { skill_manaCostBase = 39, power_skill_lightningMin = 17, power_skill_lightningMax = 317, endurance_skill_fireMin = 119, endurance_skill_fireMax = 178, frenzy_skill_coldMin = 97, frenzy_skill_coldMax = 146, }, + [14] = { skill_manaCostBase = 40, power_skill_lightningMin = 18, power_skill_lightningMax = 347, endurance_skill_fireMin = 130, endurance_skill_fireMax = 195, frenzy_skill_coldMin = 106, frenzy_skill_coldMax = 159, }, + [15] = { skill_manaCostBase = 41, power_skill_lightningMin = 20, power_skill_lightningMax = 380, endurance_skill_fireMin = 142, endurance_skill_fireMax = 213, frenzy_skill_coldMin = 116, frenzy_skill_coldMax = 174, }, + [16] = { skill_manaCostBase = 42, power_skill_lightningMin = 22, power_skill_lightningMax = 415, endurance_skill_fireMin = 155, endurance_skill_fireMax = 233, frenzy_skill_coldMin = 127, frenzy_skill_coldMax = 191, }, + [17] = { skill_manaCostBase = 44, power_skill_lightningMin = 24, power_skill_lightningMax = 454, endurance_skill_fireMin = 170, endurance_skill_fireMax = 255, frenzy_skill_coldMin = 139, frenzy_skill_coldMax = 208, }, + [18] = { skill_manaCostBase = 45, power_skill_lightningMin = 26, power_skill_lightningMax = 495, endurance_skill_fireMin = 185, endurance_skill_fireMax = 278, frenzy_skill_coldMin = 152, frenzy_skill_coldMax = 227, }, + [19] = { skill_manaCostBase = 46, power_skill_lightningMin = 28, power_skill_lightningMax = 540, endurance_skill_fireMin = 202, endurance_skill_fireMax = 303, frenzy_skill_coldMin = 165, frenzy_skill_coldMax = 248, }, + [20] = { skill_manaCostBase = 47, power_skill_lightningMin = 31, power_skill_lightningMax = 589, endurance_skill_fireMin = 220, endurance_skill_fireMax = 331, frenzy_skill_coldMin = 180, frenzy_skill_coldMax = 271, }, + [21] = { skill_manaCostBase = 48, power_skill_lightningMin = 34, power_skill_lightningMax = 642, endurance_skill_fireMin = 240, endurance_skill_fireMax = 360, frenzy_skill_coldMin = 197, frenzy_skill_coldMax = 295, }, + [22] = { skill_manaCostBase = 49, power_skill_lightningMin = 37, power_skill_lightningMax = 699, endurance_skill_fireMin = 262, endurance_skill_fireMax = 392, frenzy_skill_coldMin = 214, frenzy_skill_coldMax = 321, }, + [23] = { skill_manaCostBase = 50, power_skill_lightningMin = 40, power_skill_lightningMax = 761, endurance_skill_fireMin = 285, endurance_skill_fireMax = 427, frenzy_skill_coldMin = 233, frenzy_skill_coldMax = 349, }, + [24] = { skill_manaCostBase = 51, power_skill_lightningMin = 44, power_skill_lightningMax = 828, endurance_skill_fireMin = 310, endurance_skill_fireMax = 465, frenzy_skill_coldMin = 253, frenzy_skill_coldMax = 380, }, + [25] = { skill_manaCostBase = 52, power_skill_lightningMin = 47, power_skill_lightningMax = 900, endurance_skill_fireMin = 337, endurance_skill_fireMax = 505, frenzy_skill_coldMin = 276, frenzy_skill_coldMax = 413, }, + [26] = { skill_manaCostBase = 53, power_skill_lightningMin = 51, power_skill_lightningMax = 978, endurance_skill_fireMin = 366, endurance_skill_fireMax = 549, frenzy_skill_coldMin = 299, frenzy_skill_coldMax = 449, }, + [27] = { skill_manaCostBase = 54, power_skill_lightningMin = 56, power_skill_lightningMax = 1062, endurance_skill_fireMin = 397, endurance_skill_fireMax = 596, frenzy_skill_coldMin = 325, frenzy_skill_coldMax = 488, }, + [28] = { skill_manaCostBase = 55, power_skill_lightningMin = 61, power_skill_lightningMax = 1153, endurance_skill_fireMin = 431, endurance_skill_fireMax = 647, frenzy_skill_coldMin = 353, frenzy_skill_coldMax = 529, }, + [29] = { skill_manaCostBase = 57, power_skill_lightningMin = 66, power_skill_lightningMax = 1251, endurance_skill_fireMin = 468, endurance_skill_fireMax = 702, frenzy_skill_coldMin = 383, frenzy_skill_coldMax = 575, }, + [30] = { skill_manaCostBase = 58, power_skill_lightningMin = 71, power_skill_lightningMax = 1357, endurance_skill_fireMin = 508, endurance_skill_fireMax = 762, frenzy_skill_coldMin = 416, frenzy_skill_coldMax = 623, }, + } +} +gems["Discipline"] = { + aura = true, + spell = true, + aoe = true, + base = { + skill_manaReservedPercent = 35, + }, + quality = { + auraRadius = 1, + }, + levels = { + [1] = { auraRadiusInc = 0, energyShieldBase = 60, }, + [2] = { auraRadiusInc = 3, energyShieldBase = 70, }, + [3] = { auraRadiusInc = 6, energyShieldBase = 78, }, + [4] = { auraRadiusInc = 9, energyShieldBase = 89, }, + [5] = { auraRadiusInc = 12, energyShieldBase = 100, }, + [6] = { auraRadiusInc = 15, energyShieldBase = 111, }, + [7] = { auraRadiusInc = 18, energyShieldBase = 125, }, + [8] = { auraRadiusInc = 21, energyShieldBase = 139, }, + [9] = { auraRadiusInc = 23, energyShieldBase = 154, }, + [10] = { auraRadiusInc = 25, energyShieldBase = 165, }, + [11] = { auraRadiusInc = 27, energyShieldBase = 173, }, + [12] = { auraRadiusInc = 29, energyShieldBase = 187, }, + [13] = { auraRadiusInc = 31, energyShieldBase = 201, }, + [14] = { auraRadiusInc = 33, energyShieldBase = 213, }, + [15] = { auraRadiusInc = 35, energyShieldBase = 227, }, + [16] = { auraRadiusInc = 36, energyShieldBase = 239, }, + [17] = { auraRadiusInc = 37, energyShieldBase = 253, }, + [18] = { auraRadiusInc = 38, energyShieldBase = 269, }, + [19] = { auraRadiusInc = 39, energyShieldBase = 281, }, + [20] = { auraRadiusInc = 40, energyShieldBase = 303, }, + [21] = { auraRadiusInc = 41, energyShieldBase = 315, }, + [22] = { auraRadiusInc = 42, energyShieldBase = 330, }, + [23] = { auraRadiusInc = 43, energyShieldBase = 340, }, + [24] = { auraRadiusInc = 44, energyShieldBase = 357, }, + [25] = { auraRadiusInc = 45, energyShieldBase = 374, }, + [26] = { auraRadiusInc = 46, energyShieldBase = 384, }, + [27] = { auraRadiusInc = 47, energyShieldBase = 406, }, + [28] = { auraRadiusInc = 48, energyShieldBase = 425, }, + [29] = { auraRadiusInc = 49, energyShieldBase = 450, }, + [30] = { auraRadiusInc = 50, energyShieldBase = 455, }, + } +} +gems["Elemental Weakness"] = { + unsupported = true, +} +gems["Enfeeble"] = { + unsupported = true, +} +gems["Essence Drain"] = { + spell = true, + projectile = true, + duration = true, + chaos = true, + base = { + skill_critChanceBase = 5, + skill_damageEff = 0.6, + skill_castTime = 0.75, + skill_dotIsSpell = true, + skill_durationBase = 3.8, + }, + quality = { + chaosInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 9, skill_chaosDotBase = 21.5, skill_chaosMin = 6, skill_chaosMax = 9, }, + [2] = { skill_manaCostBase = 10, skill_chaosDotBase = 27.6, skill_chaosMin = 8, skill_chaosMax = 12, }, + [3] = { skill_manaCostBase = 11, skill_chaosDotBase = 37.6, skill_chaosMin = 11, skill_chaosMax = 16, }, + [4] = { skill_manaCostBase = 12, skill_chaosDotBase = 50.3, skill_chaosMin = 14, skill_chaosMax = 22, }, + [5] = { skill_manaCostBase = 13, skill_chaosDotBase = 66.3, skill_chaosMin = 19, skill_chaosMax = 29, }, + [6] = { skill_manaCostBase = 14, skill_chaosDotBase = 86.3, skill_chaosMin = 25, skill_chaosMax = 37, }, + [7] = { skill_manaCostBase = 16, skill_chaosDotBase = 111.3, skill_chaosMin = 32, skill_chaosMax = 48, }, + [8] = { skill_manaCostBase = 16, skill_chaosDotBase = 133.9, skill_chaosMin = 39, skill_chaosMax = 58, }, + [9] = { skill_manaCostBase = 17, skill_chaosDotBase = 160.6, skill_chaosMin = 46, skill_chaosMax = 69, }, + [10] = { skill_manaCostBase = 18, skill_chaosDotBase = 191.8, skill_chaosMin = 55, skill_chaosMax = 83, }, + [11] = { skill_manaCostBase = 19, skill_chaosDotBase = 228.5, skill_chaosMin = 66, skill_chaosMax = 99, }, + [12] = { skill_manaCostBase = 20, skill_chaosDotBase = 271.4, skill_chaosMin = 78, skill_chaosMax = 117, }, + [13] = { skill_manaCostBase = 21, skill_chaosDotBase = 321.5, skill_chaosMin = 93, skill_chaosMax = 139, }, + [14] = { skill_manaCostBase = 22, skill_chaosDotBase = 380.1, skill_chaosMin = 109, skill_chaosMax = 164, }, + [15] = { skill_manaCostBase = 23, skill_chaosDotBase = 448.3, skill_chaosMin = 129, skill_chaosMax = 194, }, + [16] = { skill_manaCostBase = 24, skill_chaosDotBase = 527.8, skill_chaosMin = 152, skill_chaosMax = 228, }, + [17] = { skill_manaCostBase = 24, skill_chaosDotBase = 587.9, skill_chaosMin = 169, skill_chaosMax = 254, }, + [18] = { skill_manaCostBase = 25, skill_chaosDotBase = 654.4, skill_chaosMin = 188, skill_chaosMax = 283, }, + [19] = { skill_manaCostBase = 26, skill_chaosDotBase = 727.8, skill_chaosMin = 210, skill_chaosMax = 314, }, + [20] = { skill_manaCostBase = 27, skill_chaosDotBase = 809, skill_chaosMin = 233, skill_chaosMax = 349, }, + [21] = { skill_manaCostBase = 28, skill_chaosDotBase = 898.7, skill_chaosMin = 259, skill_chaosMax = 388, }, + [22] = { skill_manaCostBase = 29, skill_chaosDotBase = 997.7, skill_chaosMin = 287, skill_chaosMax = 431, }, + [23] = { skill_manaCostBase = 29, skill_chaosDotBase = 1107, skill_chaosMin = 319, skill_chaosMax = 478, }, + [24] = { skill_manaCostBase = 30, skill_chaosDotBase = 1227.6, skill_chaosMin = 354, skill_chaosMax = 530, }, + [25] = { skill_manaCostBase = 30, skill_chaosDotBase = 1360.6, skill_chaosMin = 392, skill_chaosMax = 588, }, + [26] = { skill_manaCostBase = 31, skill_chaosDotBase = 1507.3, skill_chaosMin = 434, skill_chaosMax = 651, }, + [27] = { skill_manaCostBase = 32, skill_chaosDotBase = 1669.1, skill_chaosMin = 481, skill_chaosMax = 721, }, + [28] = { skill_manaCostBase = 33, skill_chaosDotBase = 1847.3, skill_chaosMin = 532, skill_chaosMax = 798, }, + [29] = { skill_manaCostBase = 33, skill_chaosDotBase = 2043.7, skill_chaosMin = 589, skill_chaosMax = 883, }, + [30] = { skill_manaCostBase = 34, skill_chaosDotBase = 2260, skill_chaosMin = 651, skill_chaosMax = 976, }, + } +} +gems["Fire Nova Mine"] = { + spell = true, + mine = true, + aoe = true, + fire = true, + base = { + skill_castTime = 1, + skill_damageEff = 0.3, + skill_critChanceBase = 5, + }, + quality = { + fireInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 12, skill_fireMin = 6, skill_fireMax = 9, }, + [2] = { skill_manaCostBase = 13, skill_fireMin = 7, skill_fireMax = 11, }, + [3] = { skill_manaCostBase = 15, skill_fireMin = 10, skill_fireMax = 14, }, + [4] = { skill_manaCostBase = 17, skill_fireMin = 12, skill_fireMax = 18, }, + [5] = { skill_manaCostBase = 18, skill_fireMin = 16, skill_fireMax = 23, }, + [6] = { skill_manaCostBase = 20, skill_fireMin = 20, skill_fireMax = 29, }, + [7] = { skill_manaCostBase = 22, skill_fireMin = 24, skill_fireMax = 36, }, + [8] = { skill_manaCostBase = 23, skill_fireMin = 28, skill_fireMax = 43, }, + [9] = { skill_manaCostBase = 24, skill_fireMin = 33, skill_fireMax = 50, }, + [10] = { skill_manaCostBase = 25, skill_fireMin = 39, skill_fireMax = 58, }, + [11] = { skill_manaCostBase = 27, skill_fireMin = 45, skill_fireMax = 67, }, + [12] = { skill_manaCostBase = 28, skill_fireMin = 52, skill_fireMax = 77, }, + [13] = { skill_manaCostBase = 29, skill_fireMin = 60, skill_fireMax = 89, }, + [14] = { skill_manaCostBase = 31, skill_fireMin = 68, skill_fireMax = 103, }, + [15] = { skill_manaCostBase = 32, skill_fireMin = 79, skill_fireMax = 118, }, + [16] = { skill_manaCostBase = 33, skill_fireMin = 90, skill_fireMax = 135, }, + [17] = { skill_manaCostBase = 34, skill_fireMin = 98, skill_fireMax = 148, }, + [18] = { skill_manaCostBase = 35, skill_fireMin = 107, skill_fireMax = 161, }, + [19] = { skill_manaCostBase = 36, skill_fireMin = 117, skill_fireMax = 176, }, + [20] = { skill_manaCostBase = 36, skill_fireMin = 128, skill_fireMax = 192, }, + [21] = { skill_manaCostBase = 37, skill_fireMin = 140, skill_fireMax = 210, }, + [22] = { skill_manaCostBase = 38, skill_fireMin = 152, skill_fireMax = 228, }, + [23] = { skill_manaCostBase = 39, skill_fireMin = 166, skill_fireMax = 249, }, + [24] = { skill_manaCostBase = 40, skill_fireMin = 181, skill_fireMax = 271, }, + [25] = { skill_manaCostBase = 41, skill_fireMin = 197, skill_fireMax = 295, }, + [26] = { skill_manaCostBase = 41, skill_fireMin = 214, skill_fireMax = 321, }, + [27] = { skill_manaCostBase = 42, skill_fireMin = 232, skill_fireMax = 349, }, + [28] = { skill_manaCostBase = 43, skill_fireMin = 253, skill_fireMax = 379, }, + [29] = { skill_manaCostBase = 44, skill_fireMin = 274, skill_fireMax = 412, }, + [30] = { skill_manaCostBase = 45, skill_fireMin = 298, skill_fireMax = 447, }, + } +} +gems["Fireball"] = { + spell = true, + aoe = true, + projectile = true, + fire = true, + base = { + skill_castTime = 0.85, + skill_damageEff = 1, + skill_critChanceBase = 6, + }, + quality = { + igniteChance = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 6, skill_fireMin = 7, skill_fireMax = 10, igniteChance = 20, }, + [2] = { skill_manaCostBase = 6, skill_fireMin = 8, skill_fireMax = 11, igniteChance = 21, }, + [3] = { skill_manaCostBase = 7, skill_fireMin = 9, skill_fireMax = 14, igniteChance = 22, }, + [4] = { skill_manaCostBase = 8, skill_fireMin = 13, skill_fireMax = 19, igniteChance = 23, }, + [5] = { skill_manaCostBase = 9, skill_fireMin = 18, skill_fireMax = 27, igniteChance = 24, }, + [6] = { skill_manaCostBase = 10, skill_fireMin = 26, skill_fireMax = 40, igniteChance = 25, }, + [7] = { skill_manaCostBase = 11, skill_fireMin = 35, skill_fireMax = 52, igniteChance = 26, }, + [8] = { skill_manaCostBase = 12, skill_fireMin = 45, skill_fireMax = 68, igniteChance = 27, }, + [9] = { skill_manaCostBase = 13, skill_fireMin = 58, skill_fireMax = 86, igniteChance = 28, }, + [10] = { skill_manaCostBase = 15, skill_fireMin = 73, skill_fireMax = 109, igniteChance = 29, }, + [11] = { skill_manaCostBase = 16, skill_fireMin = 91, skill_fireMax = 137, igniteChance = 30, }, + [12] = { skill_manaCostBase = 17, skill_fireMin = 113, skill_fireMax = 170, igniteChance = 31, }, + [13] = { skill_manaCostBase = 18, skill_fireMin = 140, skill_fireMax = 210, igniteChance = 32, }, + [14] = { skill_manaCostBase = 19, skill_fireMin = 172, skill_fireMax = 258, igniteChance = 33, }, + [15] = { skill_manaCostBase = 21, skill_fireMin = 210, skill_fireMax = 315, igniteChance = 34, }, + [16] = { skill_manaCostBase = 22, skill_fireMin = 256, skill_fireMax = 384, igniteChance = 35, }, + [17] = { skill_manaCostBase = 23, skill_fireMin = 310, skill_fireMax = 466, igniteChance = 36, }, + [18] = { skill_manaCostBase = 24, skill_fireMin = 375, skill_fireMax = 563, igniteChance = 37, }, + [19] = { skill_manaCostBase = 25, skill_fireMin = 432, skill_fireMax = 647, igniteChance = 38, }, + [20] = { skill_manaCostBase = 26, skill_fireMin = 496, skill_fireMax = 744, igniteChance = 39, }, + [21] = { skill_manaCostBase = 27, skill_fireMin = 543, skill_fireMax = 815, igniteChance = 40, }, + [22] = { skill_manaCostBase = 27, skill_fireMin = 595, skill_fireMax = 893, igniteChance = 41, }, + [23] = { skill_manaCostBase = 28, skill_fireMin = 651, skill_fireMax = 977, igniteChance = 42, }, + [24] = { skill_manaCostBase = 28, skill_fireMin = 713, skill_fireMax = 1069, igniteChance = 43, }, + [25] = { skill_manaCostBase = 29, skill_fireMin = 779, skill_fireMax = 1169, igniteChance = 44, }, + [26] = { skill_manaCostBase = 30, skill_fireMin = 852, skill_fireMax = 1278, igniteChance = 45, }, + [27] = { skill_manaCostBase = 30, skill_fireMin = 931, skill_fireMax = 1396, igniteChance = 46, }, + [28] = { skill_manaCostBase = 31, skill_fireMin = 1016, skill_fireMax = 1524, igniteChance = 47, }, + [29] = { skill_manaCostBase = 31, skill_fireMin = 1109, skill_fireMax = 1664, igniteChance = 48, }, + [30] = { skill_manaCostBase = 32, skill_fireMin = 1210, skill_fireMax = 1815, igniteChance = 49, }, + } +} +gems["Firestorm"] = { + spell = true, + aoe = true, + duration = true, + fire = true, + base = { + skill_castTime = 0.9, + skill_damageEff = 0.3, + skill_critChanceBase = 6, + skill_durationBase = 2, + }, + quality = { + damageInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 9, skill_fireMin = 4, skill_fireMax = 10, }, + [2] = { skill_manaCostBase = 10, skill_fireMin = 9, skill_fireMax = 13, }, + [3] = { skill_manaCostBase = 11, skill_fireMin = 11, skill_fireMax = 17, }, + [4] = { skill_manaCostBase = 12, skill_fireMin = 15, skill_fireMax = 22, }, + [5] = { skill_manaCostBase = 13, skill_fireMin = 19, skill_fireMax = 28, }, + [6] = { skill_manaCostBase = 14, skill_fireMin = 23, skill_fireMax = 35, }, + [7] = { skill_manaCostBase = 15, skill_fireMin = 29, skill_fireMax = 44, }, + [8] = { skill_manaCostBase = 16, skill_fireMin = 35, skill_fireMax = 52, }, + [9] = { skill_manaCostBase = 17, skill_fireMin = 40, skill_fireMax = 61, }, + [10] = { skill_manaCostBase = 18, skill_fireMin = 47, skill_fireMax = 71, }, + [11] = { skill_manaCostBase = 19, skill_fireMin = 55, skill_fireMax = 82, }, + [12] = { skill_manaCostBase = 20, skill_fireMin = 64, skill_fireMax = 95, }, + [13] = { skill_manaCostBase = 21, skill_fireMin = 74, skill_fireMax = 110, }, + [14] = { skill_manaCostBase = 22, skill_fireMin = 85, skill_fireMax = 127, }, + [15] = { skill_manaCostBase = 23, skill_fireMin = 98, skill_fireMax = 147, }, + [16] = { skill_manaCostBase = 24, skill_fireMin = 112, skill_fireMax = 169, }, + [17] = { skill_manaCostBase = 24, skill_fireMin = 123, skill_fireMax = 185, }, + [18] = { skill_manaCostBase = 25, skill_fireMin = 135, skill_fireMax = 203, }, + [19] = { skill_manaCostBase = 25, skill_fireMin = 148, skill_fireMax = 222, }, + [20] = { skill_manaCostBase = 26, skill_fireMin = 162, skill_fireMax = 243, }, + [21] = { skill_manaCostBase = 26, skill_fireMin = 177, skill_fireMax = 265, }, + [22] = { skill_manaCostBase = 27, skill_fireMin = 193, skill_fireMax = 290, }, + [23] = { skill_manaCostBase = 27, skill_fireMin = 211, skill_fireMax = 317, }, + [24] = { skill_manaCostBase = 28, skill_fireMin = 231, skill_fireMax = 346, }, + [25] = { skill_manaCostBase = 29, skill_fireMin = 251, skill_fireMax = 377, }, + [26] = { skill_manaCostBase = 30, skill_fireMin = 274, skill_fireMax = 411, }, + [27] = { skill_manaCostBase = 30, skill_fireMin = 299, skill_fireMax = 448, }, + [28] = { skill_manaCostBase = 30, skill_fireMin = 326, skill_fireMax = 488, }, + [29] = { skill_manaCostBase = 31, skill_fireMin = 355, skill_fireMax = 532, }, + [30] = { skill_manaCostBase = 32, skill_fireMin = 386, skill_fireMax = 579, }, + } +} +gems["Flame Dash"] = { + spell = true, + fire = true, + movement = true, + duration = true, + base = { + skill_castTime = 0.75, + skill_damageEff = 1, + skill_critChanceBase = 6, + skill_durationBase = 4, + }, + quality = { + castSpeedInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 10, skill_fireMin = 6, skill_fireMax = 9, skill_fireDotBase = 10.9, }, + [2] = { skill_manaCostBase = 11, skill_fireMin = 8, skill_fireMax = 11, skill_fireDotBase = 14.3, }, + [3] = { skill_manaCostBase = 12, skill_fireMin = 11, skill_fireMax = 16, skill_fireDotBase = 20, }, + [4] = { skill_manaCostBase = 13, skill_fireMin = 15, skill_fireMax = 22, skill_fireDotBase = 27.4, }, + [5] = { skill_manaCostBase = 14, skill_fireMin = 20, skill_fireMax = 29, skill_fireDotBase = 36.8, }, + [6] = { skill_manaCostBase = 15, skill_fireMin = 26, skill_fireMax = 39, skill_fireDotBase = 48.9, }, + [7] = { skill_manaCostBase = 16, skill_fireMin = 34, skill_fireMax = 51, skill_fireDotBase = 64.2, }, + [8] = { skill_manaCostBase = 17, skill_fireMin = 42, skill_fireMax = 63, skill_fireDotBase = 78.2, }, + [9] = { skill_manaCostBase = 18, skill_fireMin = 51, skill_fireMax = 76, skill_fireDotBase = 95, }, + [10] = { skill_manaCostBase = 20, skill_fireMin = 61, skill_fireMax = 92, skill_fireDotBase = 114.9, }, + [11] = { skill_manaCostBase = 21, skill_fireMin = 74, skill_fireMax = 111, skill_fireDotBase = 138.5, }, + [12] = { skill_manaCostBase = 22, skill_fireMin = 89, skill_fireMax = 133, skill_fireDotBase = 166.5, }, + [13] = { skill_manaCostBase = 24, skill_fireMin = 106, skill_fireMax = 160, skill_fireDotBase = 199.6, }, + [14] = { skill_manaCostBase = 25, skill_fireMin = 127, skill_fireMax = 191, skill_fireDotBase = 238.6, }, + [15] = { skill_manaCostBase = 26, skill_fireMin = 152, skill_fireMax = 228, skill_fireDotBase = 284.7, }, + [16] = { skill_manaCostBase = 27, skill_fireMin = 181, skill_fireMax = 271, skill_fireDotBase = 339, }, + [17] = { skill_manaCostBase = 28, skill_fireMin = 215, skill_fireMax = 322, skill_fireDotBase = 402.9, }, + [18] = { skill_manaCostBase = 29, skill_fireMin = 255, skill_fireMax = 382, skill_fireDotBase = 478.1, }, + [19] = { skill_manaCostBase = 30, skill_fireMin = 285, skill_fireMax = 428, skill_fireDotBase = 535.3, }, + [20] = { skill_manaCostBase = 30, skill_fireMin = 319, skill_fireMax = 479, skill_fireDotBase = 599, }, + [21] = { skill_manaCostBase = 31, skill_fireMin = 357, skill_fireMax = 536, skill_fireDotBase = 669.9, }, + [22] = { skill_manaCostBase = 32, skill_fireMin = 399, skill_fireMax = 599, skill_fireDotBase = 748.7, }, + [23] = { skill_manaCostBase = 33, skill_fireMin = 446, skill_fireMax = 669, skill_fireDotBase = 836.4, }, + [24] = { skill_manaCostBase = 34, skill_fireMin = 498, skill_fireMax = 747, skill_fireDotBase = 933.7, }, + [25] = { skill_manaCostBase = 34, skill_fireMin = 556, skill_fireMax = 833, skill_fireDotBase = 1041.9, }, + [26] = { skill_manaCostBase = 35, skill_fireMin = 620, skill_fireMax = 930, skill_fireDotBase = 1162, }, + [27] = { skill_manaCostBase = 36, skill_fireMin = 691, skill_fireMax = 1036, skill_fireDotBase = 1295.3, }, + [28] = { skill_manaCostBase = 37, skill_fireMin = 770, skill_fireMax = 1155, skill_fireDotBase = 1443.3, }, + [29] = { skill_manaCostBase = 38, skill_fireMin = 857, skill_fireMax = 1286, skill_fireDotBase = 1607.5, }, + [30] = { skill_manaCostBase = 38, skill_fireMin = 954, skill_fireMax = 1432, skill_fireDotBase = 1789.6, }, + } +} +gems["Flame Surge"] = { + spell = true, + aoe = true, + fire = true, + base = { + skill_castTime = 0.5, + skill_damageEff = 1, + skill_critChanceBase = 6, + condMod_EnemyBurning_damageMore = 1.5, + }, + quality = { + castSpeedInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 9, skill_fireMin = 21, skill_fireMax = 31, }, + [2] = { skill_manaCostBase = 10, skill_fireMin = 26, skill_fireMax = 39, }, + [3] = { skill_manaCostBase = 11, skill_fireMin = 35, skill_fireMax = 52, }, + [4] = { skill_manaCostBase = 12, skill_fireMin = 45, skill_fireMax = 67, }, + [5] = { skill_manaCostBase = 13, skill_fireMin = 57, skill_fireMax = 86, }, + [6] = { skill_manaCostBase = 14, skill_fireMin = 73, skill_fireMax = 109, }, + [7] = { skill_manaCostBase = 15, skill_fireMin = 91, skill_fireMax = 137, }, + [8] = { skill_manaCostBase = 16, skill_fireMin = 107, skill_fireMax = 161, }, + [9] = { skill_manaCostBase = 17, skill_fireMin = 126, skill_fireMax = 189, }, + [10] = { skill_manaCostBase = 18, skill_fireMin = 147, skill_fireMax = 221, }, + [11] = { skill_manaCostBase = 19, skill_fireMin = 171, skill_fireMax = 257, }, + [12] = { skill_manaCostBase = 20, skill_fireMin = 199, skill_fireMax = 299, }, + [13] = { skill_manaCostBase = 21, skill_fireMin = 231, skill_fireMax = 346, }, + [14] = { skill_manaCostBase = 22, skill_fireMin = 267, skill_fireMax = 401, }, + [15] = { skill_manaCostBase = 22, skill_fireMin = 308, skill_fireMax = 462, }, + [16] = { skill_manaCostBase = 23, skill_fireMin = 355, skill_fireMax = 533, }, + [17] = { skill_manaCostBase = 23, skill_fireMin = 390, skill_fireMax = 585, }, + [18] = { skill_manaCostBase = 24, skill_fireMin = 428, skill_fireMax = 642, }, + [19] = { skill_manaCostBase = 25, skill_fireMin = 469, skill_fireMax = 703, }, + [20] = { skill_manaCostBase = 26, skill_fireMin = 514, skill_fireMax = 771, }, + [21] = { skill_manaCostBase = 26, skill_fireMin = 563, skill_fireMax = 844, }, + [22] = { skill_manaCostBase = 26, skill_fireMin = 616, skill_fireMax = 923, }, + [23] = { skill_manaCostBase = 27, skill_fireMin = 673, skill_fireMax = 1010, }, + [24] = { skill_manaCostBase = 28, skill_fireMin = 736, skill_fireMax = 1104, }, + [25] = { skill_manaCostBase = 29, skill_fireMin = 804, skill_fireMax = 1206, }, + [26] = { skill_manaCostBase = 30, skill_fireMin = 878, skill_fireMax = 1317, }, + [27] = { skill_manaCostBase = 30, skill_fireMin = 958, skill_fireMax = 1437, }, + [28] = { skill_manaCostBase = 30, skill_fireMin = 1045, skill_fireMax = 1567, }, + [29] = { skill_manaCostBase = 31, skill_fireMin = 1139, skill_fireMax = 1709, }, + [30] = { skill_manaCostBase = 32, skill_fireMin = 1242, skill_fireMax = 1863, }, + } +} +gems["Flameblast"] = { + spell = true, + aoe = true, + fire = true, + parts = { + { + name = "1 Stage", + }, + { + name = "10 Stages", + }, + }, + base = { + skill_castTime = 0.2, + skill_damageEff = 0.5, + skill_critChanceBase = 5, + part2_spell_damageMore = 12, + part2_castSpeedMore = 0.1, + }, + quality = { + damageInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 6, skill_fireMin = 32, skill_fireMax = 48, }, + [2] = { skill_manaCostBase = 6, skill_fireMin = 38, skill_fireMax = 57, }, + [3] = { skill_manaCostBase = 6, skill_fireMin = 45, skill_fireMax = 67, }, + [4] = { skill_manaCostBase = 6, skill_fireMin = 52, skill_fireMax = 78, }, + [5] = { skill_manaCostBase = 7, skill_fireMin = 61, skill_fireMax = 91, }, + [6] = { skill_manaCostBase = 7, skill_fireMin = 67, skill_fireMax = 101, }, + [7] = { skill_manaCostBase = 7, skill_fireMin = 74, skill_fireMax = 111, }, + [8] = { skill_manaCostBase = 7, skill_fireMin = 82, skill_fireMax = 123, }, + [9] = { skill_manaCostBase = 7, skill_fireMin = 90, skill_fireMax = 135, }, + [10] = { skill_manaCostBase = 8, skill_fireMin = 99, skill_fireMax = 148, }, + [11] = { skill_manaCostBase = 8, skill_fireMin = 109, skill_fireMax = 163, }, + [12] = { skill_manaCostBase = 8, skill_fireMin = 119, skill_fireMax = 179, }, + [13] = { skill_manaCostBase = 8, skill_fireMin = 130, skill_fireMax = 196, }, + [14] = { skill_manaCostBase = 8, skill_fireMin = 143, skill_fireMax = 214, }, + [15] = { skill_manaCostBase = 9, skill_fireMin = 156, skill_fireMax = 234, }, + [16] = { skill_manaCostBase = 9, skill_fireMin = 171, skill_fireMax = 256, }, + [17] = { skill_manaCostBase = 9, skill_fireMin = 186, skill_fireMax = 279, }, + [18] = { skill_manaCostBase = 9, skill_fireMin = 203, skill_fireMax = 305, }, + [19] = { skill_manaCostBase = 9, skill_fireMin = 221, skill_fireMax = 332, }, + [20] = { skill_manaCostBase = 9, skill_fireMin = 241, skill_fireMax = 362, }, + [21] = { skill_manaCostBase = 10, skill_fireMin = 263, skill_fireMax = 394, }, + [22] = { skill_manaCostBase = 10, skill_fireMin = 286, skill_fireMax = 429, }, + [23] = { skill_manaCostBase = 10, skill_fireMin = 311, skill_fireMax = 466, }, + [24] = { skill_manaCostBase = 11, skill_fireMin = 338, skill_fireMax = 507, }, + [25] = { skill_manaCostBase = 11, skill_fireMin = 367, skill_fireMax = 550, }, + [26] = { skill_manaCostBase = 11, skill_fireMin = 398, skill_fireMax = 598, }, + [27] = { skill_manaCostBase = 12, skill_fireMin = 432, skill_fireMax = 649, }, + [28] = { skill_manaCostBase = 12, skill_fireMin = 469, skill_fireMax = 704, }, + [29] = { skill_manaCostBase = 12, skill_fireMin = 509, skill_fireMax = 763, }, + [30] = { skill_manaCostBase = 13, skill_fireMin = 551, skill_fireMax = 827, }, + } +} +gems["Flammability"] = { + unsupported = true, +} +gems["Flesh Offering"] = { + unsupported = true, +} +gems["Freezing Pulse"] = { + spell = true, + projectile = true, + spell = true, + base = { + skill_castTime = 0.65, + skill_damageEff = 1.25, + skill_critChanceBase = 6, + pierceChance = 100, + freezeChance = 25, + }, + quality = { + projectileSpeedInc = 2, + }, + levels = { + [1] = { skill_manaCostBase = 4, skill_coldMin = 7, skill_coldMax = 11, projectileSpeedInc = 0, }, + [2] = { skill_manaCostBase = 5, skill_coldMin = 8, skill_coldMax = 13, projectileSpeedInc = 1, }, + [3] = { skill_manaCostBase = 6, skill_coldMin = 11, skill_coldMax = 16, projectileSpeedInc = 2, }, + [4] = { skill_manaCostBase = 7, skill_coldMin = 15, skill_coldMax = 23, projectileSpeedInc = 3, }, + [5] = { skill_manaCostBase = 8, skill_coldMin = 22, skill_coldMax = 33, projectileSpeedInc = 4, }, + [6] = { skill_manaCostBase = 9, skill_coldMin = 32, skill_coldMax = 49, projectileSpeedInc = 5, }, + [7] = { skill_manaCostBase = 10, skill_coldMin = 43, skill_coldMax = 65, projectileSpeedInc = 6, }, + [8] = { skill_manaCostBase = 11, skill_coldMin = 57, skill_coldMax = 85, projectileSpeedInc = 7, }, + [9] = { skill_manaCostBase = 12, skill_coldMin = 73, skill_coldMax = 110, projectileSpeedInc = 8, }, + [10] = { skill_manaCostBase = 13, skill_coldMin = 93, skill_coldMax = 140, projectileSpeedInc = 9, }, + [11] = { skill_manaCostBase = 14, skill_coldMin = 118, skill_coldMax = 176, projectileSpeedInc = 10, }, + [12] = { skill_manaCostBase = 14, skill_coldMin = 148, skill_coldMax = 221, projectileSpeedInc = 11, }, + [13] = { skill_manaCostBase = 15, skill_coldMin = 184, skill_coldMax = 276, projectileSpeedInc = 12, }, + [14] = { skill_manaCostBase = 16, skill_coldMin = 228, skill_coldMax = 342, projectileSpeedInc = 13, }, + [15] = { skill_manaCostBase = 17, skill_coldMin = 281, skill_coldMax = 421, projectileSpeedInc = 14, }, + [16] = { skill_manaCostBase = 18, skill_coldMin = 345, skill_coldMax = 517, projectileSpeedInc = 15, }, + [17] = { skill_manaCostBase = 18, skill_coldMin = 422, skill_coldMax = 633, projectileSpeedInc = 16, }, + [18] = { skill_manaCostBase = 18, skill_coldMin = 515, skill_coldMax = 772, projectileSpeedInc = 17, }, + [19] = { skill_manaCostBase = 18, skill_coldMin = 596, skill_coldMax = 894, projectileSpeedInc = 18, }, + [20] = { skill_manaCostBase = 18, skill_coldMin = 689, skill_coldMax = 1034, projectileSpeedInc = 19, }, + [21] = { skill_manaCostBase = 18, skill_coldMin = 759, skill_coldMax = 1138, projectileSpeedInc = 20, }, + [22] = { skill_manaCostBase = 19, skill_coldMin = 835, skill_coldMax = 1252, projectileSpeedInc = 21, }, + [23] = { skill_manaCostBase = 19, skill_coldMin = 918, skill_coldMax = 1377, projectileSpeedInc = 22, }, + [24] = { skill_manaCostBase = 19, skill_coldMin = 1009, skill_coldMax = 1513, projectileSpeedInc = 23, }, + [25] = { skill_manaCostBase = 20, skill_coldMin = 1108, skill_coldMax = 1662, projectileSpeedInc = 24, }, + [26] = { skill_manaCostBase = 20, skill_coldMin = 1216, skill_coldMax = 1824, projectileSpeedInc = 25, }, + [27] = { skill_manaCostBase = 20, skill_coldMin = 1335, skill_coldMax = 2002, projectileSpeedInc = 26, }, + [28] = { skill_manaCostBase = 21, skill_coldMin = 1464, skill_coldMax = 2196, projectileSpeedInc = 27, }, + [29] = { skill_manaCostBase = 21, skill_coldMin = 1605, skill_coldMax = 2407, projectileSpeedInc = 28, }, + [30] = { skill_manaCostBase = 21, skill_coldMin = 1759, skill_coldMax = 2638, projectileSpeedInc = 29, }, + } +} +gems["Frost Bomb"] = { + unsupported = true, +} +gems["Frost Wall"] = { + unsupported = true, +} +gems["Frostbite"] = { + unsupported = true, +} +gems["Glacial Cascade"] = { + spell = true, + aoe = true, + cold = true, + base = { + skill_castTime = 0.8, + skill_damageEff = 0.6, + skill_critChanceBase = 5, + }, + quality = { + damageInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 13, skill_physicalMin = 12, skill_physicalMax = 19, skill_coldMin = 23, skill_coldMax = 35, }, + [2] = { skill_manaCostBase = 14, skill_physicalMin = 15, skill_physicalMax = 23, skill_coldMin = 28, skill_coldMax = 42, }, + [3] = { skill_manaCostBase = 15, skill_physicalMin = 18, skill_physicalMax = 27, skill_coldMin = 33, skill_coldMax = 50, }, + [4] = { skill_manaCostBase = 16, skill_physicalMin = 21, skill_physicalMax = 32, skill_coldMin = 39, skill_coldMax = 59, }, + [5] = { skill_manaCostBase = 17, skill_physicalMin = 25, skill_physicalMax = 38, skill_coldMin = 46, skill_coldMax = 69, }, + [6] = { skill_manaCostBase = 18, skill_physicalMin = 27, skill_physicalMax = 42, skill_coldMin = 51, skill_coldMax = 77, }, + [7] = { skill_manaCostBase = 18, skill_physicalMin = 31, skill_physicalMax = 47, skill_coldMin = 57, skill_coldMax = 85, }, + [8] = { skill_manaCostBase = 19, skill_physicalMin = 34, skill_physicalMax = 52, skill_coldMin = 63, skill_coldMax = 95, }, + [9] = { skill_manaCostBase = 19, skill_physicalMin = 38, skill_physicalMax = 58, skill_coldMin = 70, skill_coldMax = 105, }, + [10] = { skill_manaCostBase = 20, skill_physicalMin = 42, skill_physicalMax = 64, skill_coldMin = 77, skill_coldMax = 116, }, + [11] = { skill_manaCostBase = 21, skill_physicalMin = 46, skill_physicalMax = 71, skill_coldMin = 85, skill_coldMax = 129, }, + [12] = { skill_manaCostBase = 21, skill_physicalMin = 51, skill_physicalMax = 78, skill_coldMin = 94, skill_coldMax = 142, }, + [13] = { skill_manaCostBase = 22, skill_physicalMin = 56, skill_physicalMax = 86, skill_coldMin = 104, skill_coldMax = 157, }, + [14] = { skill_manaCostBase = 22, skill_physicalMin = 62, skill_physicalMax = 95, skill_coldMin = 115, skill_coldMax = 173, }, + [15] = { skill_manaCostBase = 23, skill_physicalMin = 68, skill_physicalMax = 105, skill_coldMin = 127, skill_coldMax = 191, }, + [16] = { skill_manaCostBase = 24, skill_physicalMin = 75, skill_physicalMax = 116, skill_coldMin = 139, skill_coldMax = 210, }, + [17] = { skill_manaCostBase = 24, skill_physicalMin = 83, skill_physicalMax = 127, skill_coldMin = 153, skill_coldMax = 231, }, + [18] = { skill_manaCostBase = 25, skill_physicalMin = 91, skill_physicalMax = 140, skill_coldMin = 169, skill_coldMax = 254, }, + [19] = { skill_manaCostBase = 25, skill_physicalMin = 100, skill_physicalMax = 154, skill_coldMin = 185, skill_coldMax = 280, }, + [20] = { skill_manaCostBase = 26, skill_physicalMin = 110, skill_physicalMax = 169, skill_coldMin = 203, skill_coldMax = 307, }, + [21] = { skill_manaCostBase = 27, skill_physicalMin = 120, skill_physicalMax = 185, skill_coldMin = 223, skill_coldMax = 337, }, + [22] = { skill_manaCostBase = 27, skill_physicalMin = 132, skill_physicalMax = 203, skill_coldMin = 245, skill_coldMax = 369, }, + [23] = { skill_manaCostBase = 28, skill_physicalMin = 145, skill_physicalMax = 223, skill_coldMin = 268, skill_coldMax = 405, }, + [24] = { skill_manaCostBase = 28, skill_physicalMin = 158, skill_physicalMax = 244, skill_coldMin = 294, skill_coldMax = 443, }, + [25] = { skill_manaCostBase = 29, skill_physicalMin = 174, skill_physicalMax = 267, skill_coldMin = 322, skill_coldMax = 485, }, + [26] = { skill_manaCostBase = 30, skill_physicalMin = 190, skill_physicalMax = 292, skill_coldMin = 352, skill_coldMax = 531, }, + [27] = { skill_manaCostBase = 30, skill_physicalMin = 208, skill_physicalMax = 319, skill_coldMin = 385, skill_coldMax = 581, }, + [28] = { skill_manaCostBase = 31, skill_physicalMin = 227, skill_physicalMax = 349, skill_coldMin = 421, skill_coldMax = 635, }, + [29] = { skill_manaCostBase = 31, skill_physicalMin = 248, skill_physicalMax = 382, skill_coldMin = 460, skill_coldMax = 694, }, + [30] = { skill_manaCostBase = 32, skill_physicalMin = 271, skill_physicalMax = 417, skill_coldMin = 502, skill_coldMax = 758, }, + } +} +gems["Herald of Thunder"] = { + cast = true, + aoe = true, + duration = true, + lightning = true, + base = { + skill_manaReservedPercent = 25, + skill_durationBase = 6, + }, + quality = { + buff_lightningInc = 0.75, + }, + levels = { + [1] = { buff_spell_lightningMin = 2, buff_spell_lightningMax = 7, buff_attack_lightningMin = 2, buff_attack_lightningMax = 7, skill_lightningMin = 1, skill_lightningMax = 34, }, + [2] = { buff_spell_lightningMin = 2, buff_spell_lightningMax = 9, buff_attack_lightningMin = 2, buff_attack_lightningMax = 9, skill_lightningMin = 1, skill_lightningMax = 47, }, + [3] = { buff_spell_lightningMin = 3, buff_spell_lightningMax = 11, buff_attack_lightningMin = 3, buff_attack_lightningMax = 11, skill_lightningMin = 1, skill_lightningMax = 65, }, + [4] = { buff_spell_lightningMin = 3, buff_spell_lightningMax = 14, buff_attack_lightningMin = 3, buff_attack_lightningMax = 14, skill_lightningMin = 2, skill_lightningMax = 87, }, + [5] = { buff_spell_lightningMin = 4, buff_spell_lightningMax = 16, buff_attack_lightningMin = 4, buff_attack_lightningMax = 16, skill_lightningMin = 2, skill_lightningMax = 108, }, + [6] = { buff_spell_lightningMin = 5, buff_spell_lightningMax = 18, buff_attack_lightningMin = 5, buff_attack_lightningMax = 18, skill_lightningMin = 3, skill_lightningMax = 135, }, + [7] = { buff_spell_lightningMin = 5, buff_spell_lightningMax = 21, buff_attack_lightningMin = 5, buff_attack_lightningMax = 21, skill_lightningMin = 3, skill_lightningMax = 166, }, + [8] = { buff_spell_lightningMin = 6, buff_spell_lightningMax = 24, buff_attack_lightningMin = 6, buff_attack_lightningMax = 24, skill_lightningMin = 4, skill_lightningMax = 203, }, + [9] = { buff_spell_lightningMin = 7, buff_spell_lightningMax = 27, buff_attack_lightningMin = 7, buff_attack_lightningMax = 27, skill_lightningMin = 5, skill_lightningMax = 248, }, + [10] = { buff_spell_lightningMin = 8, buff_spell_lightningMax = 31, buff_attack_lightningMin = 8, buff_attack_lightningMax = 31, skill_lightningMin = 6, skill_lightningMax = 301, }, + [11] = { buff_spell_lightningMin = 9, buff_spell_lightningMax = 35, buff_attack_lightningMin = 9, buff_attack_lightningMax = 35, skill_lightningMin = 8, skill_lightningMax = 363, }, + [12] = { buff_spell_lightningMin = 10, buff_spell_lightningMax = 39, buff_attack_lightningMin = 10, buff_attack_lightningMax = 39, skill_lightningMin = 9, skill_lightningMax = 436, }, + [13] = { buff_spell_lightningMin = 11, buff_spell_lightningMax = 44, buff_attack_lightningMin = 11, buff_attack_lightningMax = 44, skill_lightningMin = 11, skill_lightningMax = 522, }, + [14] = { buff_spell_lightningMin = 12, buff_spell_lightningMax = 49, buff_attack_lightningMin = 12, buff_attack_lightningMax = 49, skill_lightningMin = 13, skill_lightningMax = 623, }, + [15] = { buff_spell_lightningMin = 13, buff_spell_lightningMax = 53, buff_attack_lightningMin = 13, buff_attack_lightningMax = 53, skill_lightningMin = 15, skill_lightningMax = 708, }, + [16] = { buff_spell_lightningMin = 14, buff_spell_lightningMax = 57, buff_attack_lightningMin = 14, buff_attack_lightningMax = 57, skill_lightningMin = 17, skill_lightningMax = 803, }, + [17] = { buff_spell_lightningMin = 15, buff_spell_lightningMax = 61, buff_attack_lightningMin = 15, buff_attack_lightningMax = 61, skill_lightningMin = 19, skill_lightningMax = 908, }, + [18] = { buff_spell_lightningMin = 16, buff_spell_lightningMax = 66, buff_attack_lightningMin = 16, buff_attack_lightningMax = 66, skill_lightningMin = 21, skill_lightningMax = 1026, }, + [19] = { buff_spell_lightningMin = 18, buff_spell_lightningMax = 71, buff_attack_lightningMin = 18, buff_attack_lightningMax = 71, skill_lightningMin = 24, skill_lightningMax = 1157, }, + [20] = { buff_spell_lightningMin = 19, buff_spell_lightningMax = 76, buff_attack_lightningMin = 19, buff_attack_lightningMax = 76, skill_lightningMin = 27, skill_lightningMax = 1303, }, + [21] = { buff_spell_lightningMin = 20, buff_spell_lightningMax = 81, buff_attack_lightningMin = 20, buff_attack_lightningMax = 81, skill_lightningMin = 31, skill_lightningMax = 1451, }, + [22] = { buff_spell_lightningMin = 22, buff_spell_lightningMax = 87, buff_attack_lightningMin = 22, buff_attack_lightningMax = 87, skill_lightningMin = 34, skill_lightningMax = 1615, }, + [23] = { buff_spell_lightningMin = 23, buff_spell_lightningMax = 94, buff_attack_lightningMin = 23, buff_attack_lightningMax = 94, skill_lightningMin = 38, skill_lightningMax = 1796, }, + [24] = { buff_spell_lightningMin = 25, buff_spell_lightningMax = 100, buff_attack_lightningMin = 25, buff_attack_lightningMax = 100, skill_lightningMin = 43, skill_lightningMax = 1995, }, + [25] = { buff_spell_lightningMin = 27, buff_spell_lightningMax = 107, buff_attack_lightningMin = 27, buff_attack_lightningMax = 107, skill_lightningMin = 48, skill_lightningMax = 2215, }, + [26] = { buff_spell_lightningMin = 29, buff_spell_lightningMax = 115, buff_attack_lightningMin = 29, buff_attack_lightningMax = 115, skill_lightningMin = 54, skill_lightningMax = 2457, }, + [27] = { buff_spell_lightningMin = 31, buff_spell_lightningMax = 123, buff_attack_lightningMin = 31, buff_attack_lightningMax = 123, skill_lightningMin = 60, skill_lightningMax = 2723, }, + [28] = { buff_spell_lightningMin = 33, buff_spell_lightningMax = 131, buff_attack_lightningMin = 33, buff_attack_lightningMax = 131, skill_lightningMin = 67, skill_lightningMax = 3016, }, + [29] = { buff_spell_lightningMin = 35, buff_spell_lightningMax = 140, buff_attack_lightningMin = 35, buff_attack_lightningMax = 140, skill_lightningMin = 75, skill_lightningMax = 3338, }, + [30] = { buff_spell_lightningMin = 37, buff_spell_lightningMax = 150, buff_attack_lightningMin = 37, buff_attack_lightningMax = 150, skill_lightningMin = 83, skill_lightningMax = 3692, }, + } +} +gems["Ice Nova"] = { + spell = true, + aoe = true, + cold = true, + base = { + skill_castTime = 0.9, + skill_damageEff = 0.7, + skill_critChanceBase = 6, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 10, skill_coldMin = 14, skill_coldMax = 21, }, + [2] = { skill_manaCostBase = 11, skill_coldMin = 17, skill_coldMax = 26, }, + [3] = { skill_manaCostBase = 13, skill_coldMin = 22, skill_coldMax = 35, }, + [4] = { skill_manaCostBase = 14, skill_coldMin = 29, skill_coldMax = 46, }, + [5] = { skill_manaCostBase = 16, skill_coldMin = 38, skill_coldMax = 59, }, + [6] = { skill_manaCostBase = 17, skill_coldMin = 48, skill_coldMax = 75, }, + [7] = { skill_manaCostBase = 19, skill_coldMin = 61, skill_coldMax = 95, }, + [8] = { skill_manaCostBase = 20, skill_coldMin = 72, skill_coldMax = 113, }, + [9] = { skill_manaCostBase = 21, skill_coldMin = 85, skill_coldMax = 133, }, + [10] = { skill_manaCostBase = 22, skill_coldMin = 100, skill_coldMax = 157, }, + [11] = { skill_manaCostBase = 23, skill_coldMin = 117, skill_coldMax = 184, }, + [12] = { skill_manaCostBase = 24, skill_coldMin = 137, skill_coldMax = 215, }, + [13] = { skill_manaCostBase = 25, skill_coldMin = 160, skill_coldMax = 250, }, + [14] = { skill_manaCostBase = 26, skill_coldMin = 186, skill_coldMax = 291, }, + [15] = { skill_manaCostBase = 27, skill_coldMin = 216, skill_coldMax = 338, }, + [16] = { skill_manaCostBase = 28, skill_coldMin = 251, skill_coldMax = 392, }, + [17] = { skill_manaCostBase = 29, skill_coldMin = 277, skill_coldMax = 432, }, + [18] = { skill_manaCostBase = 30, skill_coldMin = 305, skill_coldMax = 476, }, + [19] = { skill_manaCostBase = 30, skill_coldMin = 335, skill_coldMax = 524, }, + [20] = { skill_manaCostBase = 31, skill_coldMin = 369, skill_coldMax = 577, }, + [21] = { skill_manaCostBase = 32, skill_coldMin = 406, skill_coldMax = 634, }, + [22] = { skill_manaCostBase = 33, skill_coldMin = 446, skill_coldMax = 696, }, + [23] = { skill_manaCostBase = 34, skill_coldMin = 489, skill_coldMax = 765, }, + [24] = { skill_manaCostBase = 34, skill_coldMin = 537, skill_coldMax = 839, }, + [25] = { skill_manaCostBase = 34, skill_coldMin = 589, skill_coldMax = 920, }, + [26] = { skill_manaCostBase = 34, skill_coldMin = 646, skill_coldMax = 1009, }, + [27] = { skill_manaCostBase = 35, skill_coldMin = 708, skill_coldMax = 1106, }, + [28] = { skill_manaCostBase = 35, skill_coldMin = 775, skill_coldMax = 1211, }, + [29] = { skill_manaCostBase = 35, skill_coldMin = 849, skill_coldMax = 1326, }, + [30] = { skill_manaCostBase = 35, skill_coldMin = 929, skill_coldMax = 1451, }, + } +} +gems["Ice Spear"] = { + spell = true, + projectile = true, + cold = true, + parts = { + { + name = "First Form", + }, + { + name = "Second Form", + }, + }, + base = { + skill_castTime = 0.85, + skill_damageEff = 0.8, + skill_critChanceBase = 7, + part1_pierceChance = 100, + part2_critChanceInc = 600, + }, + quality = { + projectileSpeedInc = 2, + }, + levels = { + [1] = { skill_manaCostBase = 9, skill_coldMin = 16, skill_coldMax = 24, chill_durationInc = 40, }, + [2] = { skill_manaCostBase = 10, skill_coldMin = 19, skill_coldMax = 28, chill_durationInc = 42, }, + [3] = { skill_manaCostBase = 11, skill_coldMin = 24, skill_coldMax = 36, chill_durationInc = 44, }, + [4] = { skill_manaCostBase = 12, skill_coldMin = 30, skill_coldMax = 45, chill_durationInc = 46, }, + [5] = { skill_manaCostBase = 13, skill_coldMin = 38, skill_coldMax = 57, chill_durationInc = 48, }, + [6] = { skill_manaCostBase = 14, skill_coldMin = 48, skill_coldMax = 72, chill_durationInc = 50, }, + [7] = { skill_manaCostBase = 16, skill_coldMin = 60, skill_coldMax = 90, chill_durationInc = 52, }, + [8] = { skill_manaCostBase = 16, skill_coldMin = 70, skill_coldMax = 105, chill_durationInc = 54, }, + [9] = { skill_manaCostBase = 17, skill_coldMin = 82, skill_coldMax = 123, chill_durationInc = 56, }, + [10] = { skill_manaCostBase = 18, skill_coldMin = 96, skill_coldMax = 143, chill_durationInc = 58, }, + [11] = { skill_manaCostBase = 19, skill_coldMin = 111, skill_coldMax = 166, chill_durationInc = 60, }, + [12] = { skill_manaCostBase = 20, skill_coldMin = 128, skill_coldMax = 192, chill_durationInc = 62, }, + [13] = { skill_manaCostBase = 21, skill_coldMin = 148, skill_coldMax = 222, chill_durationInc = 64, }, + [14] = { skill_manaCostBase = 22, skill_coldMin = 171, skill_coldMax = 256, chill_durationInc = 66, }, + [15] = { skill_manaCostBase = 23, skill_coldMin = 196, skill_coldMax = 294, chill_durationInc = 68, }, + [16] = { skill_manaCostBase = 24, skill_coldMin = 225, skill_coldMax = 337, chill_durationInc = 70, }, + [17] = { skill_manaCostBase = 24, skill_coldMin = 246, skill_coldMax = 369, chill_durationInc = 72, }, + [18] = { skill_manaCostBase = 25, skill_coldMin = 269, skill_coldMax = 404, chill_durationInc = 74, }, + [19] = { skill_manaCostBase = 26, skill_coldMin = 294, skill_coldMax = 441, chill_durationInc = 76, }, + [20] = { skill_manaCostBase = 27, skill_coldMin = 321, skill_coldMax = 482, chill_durationInc = 78, }, + [21] = { skill_manaCostBase = 28, skill_coldMin = 351, skill_coldMax = 526, chill_durationInc = 80, }, + [22] = { skill_manaCostBase = 29, skill_coldMin = 383, skill_coldMax = 574, chill_durationInc = 82, }, + [23] = { skill_manaCostBase = 29, skill_coldMin = 418, skill_coldMax = 626, chill_durationInc = 84, }, + [24] = { skill_manaCostBase = 30, skill_coldMin = 455, skill_coldMax = 683, chill_durationInc = 86, }, + [25] = { skill_manaCostBase = 30, skill_coldMin = 496, skill_coldMax = 744, chill_durationInc = 88, }, + [26] = { skill_manaCostBase = 31, skill_coldMin = 540, skill_coldMax = 810, chill_durationInc = 90, }, + [27] = { skill_manaCostBase = 32, skill_coldMin = 587, skill_coldMax = 881, chill_durationInc = 92, }, + [28] = { skill_manaCostBase = 33, skill_coldMin = 639, skill_coldMax = 958, chill_durationInc = 94, }, + [29] = { skill_manaCostBase = 33, skill_coldMin = 695, skill_coldMax = 1042, chill_durationInc = 96, }, + [30] = { skill_manaCostBase = 34, skill_coldMin = 755, skill_coldMax = 1132, chill_durationInc = 98, }, + } +} +gems["Incinerate"] = { + spell = true, + projectile = true, + fire = true, + parts = { + { + name = "Base damage", + }, + { + name = "Fully charged", + }, + }, + base = { + skill_castTime = 0.2, + skill_damageEff = 0.3, + skill_baseCrit = 0, + pierceChance = 100, + part2_spell_damageMore = 2.5, + }, + quality = { + projectileSpeedInc = 2, + }, + levels = { + [1] = { skill_manaCostBase = 6, skill_fireMin = 6, skill_fireMax = 9, }, + [2] = { skill_manaCostBase = 6, skill_fireMin = 7, skill_fireMax = 11, }, + [3] = { skill_manaCostBase = 6, skill_fireMin = 10, skill_fireMax = 15, }, + [4] = { skill_manaCostBase = 6, skill_fireMin = 13, skill_fireMax = 19, }, + [5] = { skill_manaCostBase = 6, skill_fireMin = 16, skill_fireMax = 24, }, + [6] = { skill_manaCostBase = 6, skill_fireMin = 20, skill_fireMax = 31, }, + [7] = { skill_manaCostBase = 6, skill_fireMin = 25, skill_fireMax = 38, }, + [8] = { skill_manaCostBase = 6, skill_fireMin = 30, skill_fireMax = 45, }, + [9] = { skill_manaCostBase = 7, skill_fireMin = 35, skill_fireMax = 52, }, + [10] = { skill_manaCostBase = 7, skill_fireMin = 41, skill_fireMax = 61, }, + [11] = { skill_manaCostBase = 7, skill_fireMin = 47, skill_fireMax = 71, }, + [12] = { skill_manaCostBase = 7, skill_fireMin = 54, skill_fireMax = 82, }, + [13] = { skill_manaCostBase = 7, skill_fireMin = 63, skill_fireMax = 94, }, + [14] = { skill_manaCostBase = 7, skill_fireMin = 72, skill_fireMax = 108, }, + [15] = { skill_manaCostBase = 8, skill_fireMin = 83, skill_fireMax = 125, }, + [16] = { skill_manaCostBase = 8, skill_fireMin = 95, skill_fireMax = 143, }, + [17] = { skill_manaCostBase = 8, skill_fireMin = 104, skill_fireMax = 157, }, + [18] = { skill_manaCostBase = 8, skill_fireMin = 114, skill_fireMax = 171, }, + [19] = { skill_manaCostBase = 8, skill_fireMin = 125, skill_fireMax = 187, }, + [20] = { skill_manaCostBase = 9, skill_fireMin = 136, skill_fireMax = 204, }, + [21] = { skill_manaCostBase = 9, skill_fireMin = 149, skill_fireMax = 223, }, + [22] = { skill_manaCostBase = 9, skill_fireMin = 162, skill_fireMax = 244, }, + [23] = { skill_manaCostBase = 9, skill_fireMin = 177, skill_fireMax = 266, }, + [24] = { skill_manaCostBase = 9, skill_fireMin = 193, skill_fireMax = 289, }, + [25] = { skill_manaCostBase = 9, skill_fireMin = 210, skill_fireMax = 315, }, + [26] = { skill_manaCostBase = 10, skill_fireMin = 229, skill_fireMax = 343, }, + [27] = { skill_manaCostBase = 10, skill_fireMin = 249, skill_fireMax = 374, }, + [28] = { skill_manaCostBase = 10, skill_fireMin = 271, skill_fireMax = 406, }, + [29] = { skill_manaCostBase = 10, skill_fireMin = 295, skill_fireMax = 442, }, + [30] = { skill_manaCostBase = 10, skill_fireMin = 320, skill_fireMax = 480, }, + } +} +gems["Kinetic Blast"] = { + attack = true, + projectile = true, + aoe = true, + parts = { + { + name = "Projectile", + aoe = false, + }, + { + name = "Explosions", + }, + }, + base = { + part2_damageMore = 0.75, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 15, attack_damageMore = 1.2, aoeRadiusInc = 0, }, + [2] = { skill_manaCostBase = 15, attack_damageMore = 1.214, aoeRadiusInc = 1, }, + [3] = { skill_manaCostBase = 15, attack_damageMore = 1.228, aoeRadiusInc = 2, }, + [4] = { skill_manaCostBase = 15, attack_damageMore = 1.242, aoeRadiusInc = 3, }, + [5] = { skill_manaCostBase = 15, attack_damageMore = 1.256, aoeRadiusInc = 4, }, + [6] = { skill_manaCostBase = 15, attack_damageMore = 1.27, aoeRadiusInc = 5, }, + [7] = { skill_manaCostBase = 15, attack_damageMore = 1.284, aoeRadiusInc = 6, }, + [8] = { skill_manaCostBase = 15, attack_damageMore = 1.298, aoeRadiusInc = 7, }, + [9] = { skill_manaCostBase = 16, attack_damageMore = 1.312, aoeRadiusInc = 8, }, + [10] = { skill_manaCostBase = 16, attack_damageMore = 1.326, aoeRadiusInc = 9, }, + [11] = { skill_manaCostBase = 16, attack_damageMore = 1.34, aoeRadiusInc = 10, }, + [12] = { skill_manaCostBase = 16, attack_damageMore = 1.354, aoeRadiusInc = 11, }, + [13] = { skill_manaCostBase = 16, attack_damageMore = 1.368, aoeRadiusInc = 12, }, + [14] = { skill_manaCostBase = 16, attack_damageMore = 1.382, aoeRadiusInc = 13, }, + [15] = { skill_manaCostBase = 16, attack_damageMore = 1.396, aoeRadiusInc = 14, }, + [16] = { skill_manaCostBase = 16, attack_damageMore = 1.41, aoeRadiusInc = 15, }, + [17] = { skill_manaCostBase = 16, attack_damageMore = 1.424, aoeRadiusInc = 16, }, + [18] = { skill_manaCostBase = 16, attack_damageMore = 1.438, aoeRadiusInc = 17, }, + [19] = { skill_manaCostBase = 16, attack_damageMore = 1.452, aoeRadiusInc = 18, }, + [20] = { skill_manaCostBase = 16, attack_damageMore = 1.466, aoeRadiusInc = 19, }, + [21] = { skill_manaCostBase = 16, attack_damageMore = 1.48, aoeRadiusInc = 20, }, + [22] = { skill_manaCostBase = 16, attack_damageMore = 1.494, aoeRadiusInc = 21, }, + [23] = { skill_manaCostBase = 16, attack_damageMore = 1.508, aoeRadiusInc = 22, }, + [24] = { skill_manaCostBase = 16, attack_damageMore = 1.522, aoeRadiusInc = 23, }, + [25] = { skill_manaCostBase = 17, attack_damageMore = 1.536, aoeRadiusInc = 24, }, + [26] = { skill_manaCostBase = 17, attack_damageMore = 1.55, aoeRadiusInc = 25, }, + [27] = { skill_manaCostBase = 17, attack_damageMore = 1.564, aoeRadiusInc = 26, }, + [28] = { skill_manaCostBase = 17, attack_damageMore = 1.578, aoeRadiusInc = 27, }, + [29] = { skill_manaCostBase = 17, attack_damageMore = 1.592, aoeRadiusInc = 28, }, + [30] = { skill_manaCostBase = 17, attack_damageMore = 1.606, aoeRadiusInc = 29, }, + } +} +gems["Lightning Tendrils"] = { + spell = true, + aoe = true, + lightning = true, + base = { + skill_castTime = 0.8, + skill_damageEff = 0.35, + skill_critChanceBase = 6, + }, + quality = { + lightningInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 6, skill_lightningMin = 1, skill_lightningMax = 3, }, + [2] = { skill_manaCostBase = 7, skill_lightningMin = 1, skill_lightningMax = 4, }, + [3] = { skill_manaCostBase = 8, skill_lightningMin = 1, skill_lightningMax = 5, }, + [4] = { skill_manaCostBase = 9, skill_lightningMin = 1, skill_lightningMax = 7, }, + [5] = { skill_manaCostBase = 10, skill_lightningMin = 1, skill_lightningMax = 10, }, + [6] = { skill_manaCostBase = 11, skill_lightningMin = 1, skill_lightningMax = 16, }, + [7] = { skill_manaCostBase = 12, skill_lightningMin = 1, skill_lightningMax = 21, }, + [8] = { skill_manaCostBase = 13, skill_lightningMin = 1, skill_lightningMax = 28, }, + [9] = { skill_manaCostBase = 14, skill_lightningMin = 2, skill_lightningMax = 38, }, + [10] = { skill_manaCostBase = 16, skill_lightningMin = 3, skill_lightningMax = 49, }, + [11] = { skill_manaCostBase = 18, skill_lightningMin = 3, skill_lightningMax = 64, }, + [12] = { skill_manaCostBase = 19, skill_lightningMin = 4, skill_lightningMax = 82, }, + [13] = { skill_manaCostBase = 20, skill_lightningMin = 6, skill_lightningMax = 105, }, + [14] = { skill_manaCostBase = 21, skill_lightningMin = 7, skill_lightningMax = 133, }, + [15] = { skill_manaCostBase = 22, skill_lightningMin = 9, skill_lightningMax = 168, }, + [16] = { skill_manaCostBase = 23, skill_lightningMin = 11, skill_lightningMax = 212, }, + [17] = { skill_manaCostBase = 24, skill_lightningMin = 14, skill_lightningMax = 265, }, + [18] = { skill_manaCostBase = 25, skill_lightningMin = 17, skill_lightningMax = 332, }, + [19] = { skill_manaCostBase = 26, skill_lightningMin = 21, skill_lightningMax = 392, }, + [20] = { skill_manaCostBase = 26, skill_lightningMin = 24, skill_lightningMax = 461, }, + [21] = { skill_manaCostBase = 27, skill_lightningMin = 27, skill_lightningMax = 514, }, + [22] = { skill_manaCostBase = 27, skill_lightningMin = 30, skill_lightningMax = 573, }, + [23] = { skill_manaCostBase = 28, skill_lightningMin = 34, skill_lightningMax = 638, }, + [24] = { skill_manaCostBase = 28, skill_lightningMin = 37, skill_lightningMax = 710, }, + [25] = { skill_manaCostBase = 29, skill_lightningMin = 42, skill_lightningMax = 790, }, + [26] = { skill_manaCostBase = 29, skill_lightningMin = 46, skill_lightningMax = 878, }, + [27] = { skill_manaCostBase = 30, skill_lightningMin = 51, skill_lightningMax = 975, }, + [28] = { skill_manaCostBase = 30, skill_lightningMin = 57, skill_lightningMax = 1083, }, + [29] = { skill_manaCostBase = 31, skill_lightningMin = 63, skill_lightningMax = 1202, }, + [30] = { skill_manaCostBase = 31, skill_lightningMin = 70, skill_lightningMax = 1334, }, + } +} +gems["Lightning Trap"] = { + spell = true, + trap = true, + projectile = true, + lightning = true, + base = { + skill_castTime = 1, + skill_damageEff = 0.9, + skill_critChanceBase = 5, + }, + quality = { + trapThrowingSpeedInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 8, skill_lightningMin = 3, skill_lightningMax = 62, }, + [2] = { skill_manaCostBase = 9, skill_lightningMin = 4, skill_lightningMax = 77, }, + [3] = { skill_manaCostBase = 10, skill_lightningMin = 5, skill_lightningMax = 98, }, + [4] = { skill_manaCostBase = 10, skill_lightningMin = 7, skill_lightningMax = 124, }, + [5] = { skill_manaCostBase = 11, skill_lightningMin = 8, skill_lightningMax = 153, }, + [6] = { skill_manaCostBase = 12, skill_lightningMin = 10, skill_lightningMax = 188, }, + [7] = { skill_manaCostBase = 13, skill_lightningMin = 12, skill_lightningMax = 228, }, + [8] = { skill_manaCostBase = 14, skill_lightningMin = 14, skill_lightningMax = 263, }, + [9] = { skill_manaCostBase = 14, skill_lightningMin = 16, skill_lightningMax = 301, }, + [10] = { skill_manaCostBase = 16, skill_lightningMin = 18, skill_lightningMax = 344, }, + [11] = { skill_manaCostBase = 17, skill_lightningMin = 21, skill_lightningMax = 391, }, + [12] = { skill_manaCostBase = 18, skill_lightningMin = 23, skill_lightningMax = 444, }, + [13] = { skill_manaCostBase = 19, skill_lightningMin = 26, skill_lightningMax = 503, }, + [14] = { skill_manaCostBase = 20, skill_lightningMin = 30, skill_lightningMax = 568, }, + [15] = { skill_manaCostBase = 21, skill_lightningMin = 34, skill_lightningMax = 640, }, + [16] = { skill_manaCostBase = 22, skill_lightningMin = 38, skill_lightningMax = 720, }, + [17] = { skill_manaCostBase = 22, skill_lightningMin = 41, skill_lightningMax = 779, }, + [18] = { skill_manaCostBase = 23, skill_lightningMin = 44, skill_lightningMax = 841, }, + [19] = { skill_manaCostBase = 24, skill_lightningMin = 48, skill_lightningMax = 907, }, + [20] = { skill_manaCostBase = 24, skill_lightningMin = 52, skill_lightningMax = 979, }, + [21] = { skill_manaCostBase = 25, skill_lightningMin = 56, skill_lightningMax = 1055, }, + [22] = { skill_manaCostBase = 26, skill_lightningMin = 60, skill_lightningMax = 1136, }, + [23] = { skill_manaCostBase = 26, skill_lightningMin = 64, skill_lightningMax = 1223, }, + [24] = { skill_manaCostBase = 27, skill_lightningMin = 69, skill_lightningMax = 1316, }, + [25] = { skill_manaCostBase = 27, skill_lightningMin = 74, skill_lightningMax = 1415, }, + [26] = { skill_manaCostBase = 28, skill_lightningMin = 80, skill_lightningMax = 1521, }, + [27] = { skill_manaCostBase = 29, skill_lightningMin = 86, skill_lightningMax = 1634, }, + [28] = { skill_manaCostBase = 30, skill_lightningMin = 92, skill_lightningMax = 1755, }, + [29] = { skill_manaCostBase = 30, skill_lightningMin = 99, skill_lightningMax = 1884, }, + [30] = { skill_manaCostBase = 30, skill_lightningMin = 106, skill_lightningMax = 2021, }, + } +} +gems["Lightning Warp"] = { + spell = true, + aoe = true, + lightning = true, + movement = true, + duration = true, + base = { + skill_castTime = 1, + skill_damageEff = 0.6, + skill_critChanceBase = 5, + }, + quality = { + castSpeedInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 15, skill_lightningMin = 1, skill_lightningMax = 19, durationInc = -0, }, + [2] = { skill_manaCostBase = 16, skill_lightningMin = 1, skill_lightningMax = 24, durationInc = -2, }, + [3] = { skill_manaCostBase = 17, skill_lightningMin = 2, skill_lightningMax = 33, durationInc = -4, }, + [4] = { skill_manaCostBase = 18, skill_lightningMin = 2, skill_lightningMax = 44, durationInc = -6, }, + [5] = { skill_manaCostBase = 18, skill_lightningMin = 3, skill_lightningMax = 58, durationInc = -8, }, + [6] = { skill_manaCostBase = 20, skill_lightningMin = 4, skill_lightningMax = 75, durationInc = -10, }, + [7] = { skill_manaCostBase = 21, skill_lightningMin = 5, skill_lightningMax = 96, durationInc = -12, }, + [8] = { skill_manaCostBase = 22, skill_lightningMin = 6, skill_lightningMax = 115, durationInc = -14, }, + [9] = { skill_manaCostBase = 23, skill_lightningMin = 7, skill_lightningMax = 137, durationInc = -16, }, + [10] = { skill_manaCostBase = 24, skill_lightningMin = 9, skill_lightningMax = 162, durationInc = -18, }, + [11] = { skill_manaCostBase = 26, skill_lightningMin = 10, skill_lightningMax = 192, durationInc = -20, }, + [12] = { skill_manaCostBase = 26, skill_lightningMin = 12, skill_lightningMax = 226, durationInc = -22, }, + [13] = { skill_manaCostBase = 27, skill_lightningMin = 14, skill_lightningMax = 266, durationInc = -24, }, + [14] = { skill_manaCostBase = 28, skill_lightningMin = 16, skill_lightningMax = 312, durationInc = -26, }, + [15] = { skill_manaCostBase = 29, skill_lightningMin = 19, skill_lightningMax = 365, durationInc = -28, }, + [16] = { skill_manaCostBase = 30, skill_lightningMin = 22, skill_lightningMax = 426, durationInc = -30, }, + [17] = { skill_manaCostBase = 30, skill_lightningMin = 26, skill_lightningMax = 497, durationInc = -32, }, + [18] = { skill_manaCostBase = 31, skill_lightningMin = 30, skill_lightningMax = 579, durationInc = -34, }, + [19] = { skill_manaCostBase = 32, skill_lightningMin = 34, skill_lightningMax = 640, durationInc = -36, }, + [20] = { skill_manaCostBase = 33, skill_lightningMin = 37, skill_lightningMax = 707, durationInc = -38, }, + [21] = { skill_manaCostBase = 34, skill_lightningMin = 41, skill_lightningMax = 780, durationInc = -40, }, + [22] = { skill_manaCostBase = 34, skill_lightningMin = 45, skill_lightningMax = 861, durationInc = -42, }, + [23] = { skill_manaCostBase = 34, skill_lightningMin = 50, skill_lightningMax = 949, durationInc = -44, }, + [24] = { skill_manaCostBase = 34, skill_lightningMin = 55, skill_lightningMax = 1046, durationInc = -46, }, + [25] = { skill_manaCostBase = 35, skill_lightningMin = 61, skill_lightningMax = 1152, durationInc = -48, }, + [26] = { skill_manaCostBase = 35, skill_lightningMin = 67, skill_lightningMax = 1269, durationInc = -50, }, + [27] = { skill_manaCostBase = 36, skill_lightningMin = 73, skill_lightningMax = 1396, durationInc = -52, }, + [28] = { skill_manaCostBase = 37, skill_lightningMin = 81, skill_lightningMax = 1536, durationInc = -54, }, + [29] = { skill_manaCostBase = 37, skill_lightningMin = 89, skill_lightningMax = 1689, durationInc = -56, }, + [30] = { skill_manaCostBase = 37, skill_lightningMin = 98, skill_lightningMax = 1856, durationInc = -58, }, + } +} +gems["Magma Orb"] = { + spell = true, + projectile = true, + aoe = true, + fire = true, + base = { + skill_castTime = 0.7, + skill_damageEff = 1.25, + skill_critChanceBase = 5, + }, + quality = { + damageInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 5, skill_fireMin = 6, skill_fireMax = 9, }, + [2] = { skill_manaCostBase = 6, skill_fireMin = 7, skill_fireMax = 10, }, + [3] = { skill_manaCostBase = 6, skill_fireMin = 8, skill_fireMax = 12, }, + [4] = { skill_manaCostBase = 7, skill_fireMin = 11, skill_fireMax = 17, }, + [5] = { skill_manaCostBase = 7, skill_fireMin = 16, skill_fireMax = 24, }, + [6] = { skill_manaCostBase = 8, skill_fireMin = 25, skill_fireMax = 37, }, + [7] = { skill_manaCostBase = 9, skill_fireMin = 33, skill_fireMax = 50, }, + [8] = { skill_manaCostBase = 10, skill_fireMin = 44, skill_fireMax = 66, }, + [9] = { skill_manaCostBase = 11, skill_fireMin = 58, skill_fireMax = 87, }, + [10] = { skill_manaCostBase = 12, skill_fireMin = 75, skill_fireMax = 112, }, + [11] = { skill_manaCostBase = 13, skill_fireMin = 96, skill_fireMax = 144, }, + [12] = { skill_manaCostBase = 14, skill_fireMin = 122, skill_fireMax = 183, }, + [13] = { skill_manaCostBase = 15, skill_fireMin = 154, skill_fireMax = 232, }, + [14] = { skill_manaCostBase = 16, skill_fireMin = 194, skill_fireMax = 291, }, + [15] = { skill_manaCostBase = 18, skill_fireMin = 243, skill_fireMax = 365, }, + [16] = { skill_manaCostBase = 19, skill_fireMin = 303, skill_fireMax = 454, }, + [17] = { skill_manaCostBase = 20, skill_fireMin = 376, skill_fireMax = 564, }, + [18] = { skill_manaCostBase = 21, skill_fireMin = 466, skill_fireMax = 698, }, + [19] = { skill_manaCostBase = 21, skill_fireMin = 545, skill_fireMax = 818, }, + [20] = { skill_manaCostBase = 22, skill_fireMin = 637, skill_fireMax = 956, }, + [21] = { skill_manaCostBase = 23, skill_fireMin = 707, skill_fireMax = 1060, }, + [22] = { skill_manaCostBase = 23, skill_fireMin = 784, skill_fireMax = 1175, }, + [23] = { skill_manaCostBase = 24, skill_fireMin = 868, skill_fireMax = 1302, }, + [24] = { skill_manaCostBase = 24, skill_fireMin = 961, skill_fireMax = 1442, }, + [25] = { skill_manaCostBase = 25, skill_fireMin = 1063, skill_fireMax = 1595, }, + [26] = { skill_manaCostBase = 26, skill_fireMin = 1176, skill_fireMax = 1764, }, + [27] = { skill_manaCostBase = 26, skill_fireMin = 1300, skill_fireMax = 1950, }, + [28] = { skill_manaCostBase = 27, skill_fireMin = 1437, skill_fireMax = 2155, }, + [29] = { skill_manaCostBase = 27, skill_fireMin = 1587, skill_fireMax = 2380, }, + [30] = { skill_manaCostBase = 28, skill_fireMin = 1752, skill_fireMax = 2628, }, + } +} +gems["Orb of Storms"] = { + unsupported = true, +} +gems["Power Siphon"] = { + attack = true, + projectile = true, + base = { + }, + quality = { + damageInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 13, attack_damageMore = 1.3, }, + [2] = { skill_manaCostBase = 13, attack_damageMore = 1.316, }, + [3] = { skill_manaCostBase = 13, attack_damageMore = 1.332, }, + [4] = { skill_manaCostBase = 13, attack_damageMore = 1.348, }, + [5] = { skill_manaCostBase = 13, attack_damageMore = 1.364, }, + [6] = { skill_manaCostBase = 13, attack_damageMore = 1.38, }, + [7] = { skill_manaCostBase = 13, attack_damageMore = 1.396, }, + [8] = { skill_manaCostBase = 14, attack_damageMore = 1.412, }, + [9] = { skill_manaCostBase = 14, attack_damageMore = 1.428, }, + [10] = { skill_manaCostBase = 14, attack_damageMore = 1.444, }, + [11] = { skill_manaCostBase = 14, attack_damageMore = 1.46, }, + [12] = { skill_manaCostBase = 14, attack_damageMore = 1.476, }, + [13] = { skill_manaCostBase = 14, attack_damageMore = 1.492, }, + [14] = { skill_manaCostBase = 14, attack_damageMore = 1.508, }, + [15] = { skill_manaCostBase = 14, attack_damageMore = 1.524, }, + [16] = { skill_manaCostBase = 14, attack_damageMore = 1.54, }, + [17] = { skill_manaCostBase = 14, attack_damageMore = 1.556, }, + [18] = { skill_manaCostBase = 14, attack_damageMore = 1.572, }, + [19] = { skill_manaCostBase = 15, attack_damageMore = 1.588, }, + [20] = { skill_manaCostBase = 15, attack_damageMore = 1.604, }, + [21] = { skill_manaCostBase = 15, attack_damageMore = 1.62, }, + [22] = { skill_manaCostBase = 15, attack_damageMore = 1.636, }, + [23] = { skill_manaCostBase = 15, attack_damageMore = 1.652, }, + [24] = { skill_manaCostBase = 15, attack_damageMore = 1.668, }, + [25] = { skill_manaCostBase = 15, attack_damageMore = 1.684, }, + [26] = { skill_manaCostBase = 16, attack_damageMore = 1.7, }, + [27] = { skill_manaCostBase = 16, attack_damageMore = 1.716, }, + [28] = { skill_manaCostBase = 16, attack_damageMore = 1.732, }, + [29] = { skill_manaCostBase = 16, attack_damageMore = 1.748, }, + [30] = { skill_manaCostBase = 16, attack_damageMore = 1.764, }, + } +} +gems["Purity of Elements"] = { + aura = true, + spell = true, + aoe = true, + base = { + skill_manaReservedPercent = 35, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { auraRadiusInc = 0, elemResistBase = 12, }, + [2] = { auraRadiusInc = 3, elemResistBase = 13, }, + [3] = { auraRadiusInc = 6, elemResistBase = 14, }, + [4] = { auraRadiusInc = 9, elemResistBase = 15, }, + [5] = { auraRadiusInc = 12, elemResistBase = 15, }, + [6] = { auraRadiusInc = 15, elemResistBase = 16, }, + [7] = { auraRadiusInc = 18, elemResistBase = 17, }, + [8] = { auraRadiusInc = 21, elemResistBase = 18, }, + [9] = { auraRadiusInc = 23, elemResistBase = 19, }, + [10] = { auraRadiusInc = 25, elemResistBase = 20, }, + [11] = { auraRadiusInc = 27, elemResistBase = 20, }, + [12] = { auraRadiusInc = 29, elemResistBase = 21, }, + [13] = { auraRadiusInc = 31, elemResistBase = 22, }, + [14] = { auraRadiusInc = 33, elemResistBase = 23, }, + [15] = { auraRadiusInc = 35, elemResistBase = 24, }, + [16] = { auraRadiusInc = 36, elemResistBase = 25, }, + [17] = { auraRadiusInc = 37, elemResistBase = 25, }, + [18] = { auraRadiusInc = 38, elemResistBase = 26, }, + [19] = { auraRadiusInc = 39, elemResistBase = 27, }, + [20] = { auraRadiusInc = 40, elemResistBase = 27, }, + [21] = { auraRadiusInc = 41, elemResistBase = 28, }, + [22] = { auraRadiusInc = 42, elemResistBase = 29, }, + [23] = { auraRadiusInc = 43, elemResistBase = 29, }, + [24] = { auraRadiusInc = 44, elemResistBase = 30, }, + [25] = { auraRadiusInc = 45, elemResistBase = 31, }, + [26] = { auraRadiusInc = 46, elemResistBase = 31, }, + [27] = { auraRadiusInc = 47, elemResistBase = 32, }, + [28] = { auraRadiusInc = 48, elemResistBase = 33, }, + [29] = { auraRadiusInc = 49, elemResistBase = 33, }, + [30] = { auraRadiusInc = 50, elemResistBase = 34, }, + } +} +gems["Purity of Lightning"] = { + aura = true, + spell = true, + aoe = true, + lightning = true, + base = { + skill_manaReservedPercent = 35, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { auraRadiusInc = 0, lightningResistBase = 22, lightningResistMaxBase = 0, }, + [2] = { auraRadiusInc = 3, lightningResistBase = 23, lightningResistMaxBase = 0, }, + [3] = { auraRadiusInc = 6, lightningResistBase = 24, lightningResistMaxBase = 0, }, + [4] = { auraRadiusInc = 9, lightningResistBase = 25, lightningResistMaxBase = 0, }, + [5] = { auraRadiusInc = 12, lightningResistBase = 26, lightningResistMaxBase = 1, }, + [6] = { auraRadiusInc = 15, lightningResistBase = 27, lightningResistMaxBase = 1, }, + [7] = { auraRadiusInc = 18, lightningResistBase = 28, lightningResistMaxBase = 1, }, + [8] = { auraRadiusInc = 21, lightningResistBase = 29, lightningResistMaxBase = 1, }, + [9] = { auraRadiusInc = 23, lightningResistBase = 30, lightningResistMaxBase = 1, }, + [10] = { auraRadiusInc = 25, lightningResistBase = 31, lightningResistMaxBase = 1, }, + [11] = { auraRadiusInc = 27, lightningResistBase = 32, lightningResistMaxBase = 2, }, + [12] = { auraRadiusInc = 29, lightningResistBase = 33, lightningResistMaxBase = 2, }, + [13] = { auraRadiusInc = 31, lightningResistBase = 34, lightningResistMaxBase = 2, }, + [14] = { auraRadiusInc = 33, lightningResistBase = 35, lightningResistMaxBase = 2, }, + [15] = { auraRadiusInc = 35, lightningResistBase = 36, lightningResistMaxBase = 2, }, + [16] = { auraRadiusInc = 36, lightningResistBase = 37, lightningResistMaxBase = 2, }, + [17] = { auraRadiusInc = 37, lightningResistBase = 38, lightningResistMaxBase = 3, }, + [18] = { auraRadiusInc = 38, lightningResistBase = 39, lightningResistMaxBase = 3, }, + [19] = { auraRadiusInc = 39, lightningResistBase = 40, lightningResistMaxBase = 3, }, + [20] = { auraRadiusInc = 40, lightningResistBase = 41, lightningResistMaxBase = 4, }, + [21] = { auraRadiusInc = 41, lightningResistBase = 42, lightningResistMaxBase = 4, }, + [22] = { auraRadiusInc = 42, lightningResistBase = 43, lightningResistMaxBase = 4, }, + [23] = { auraRadiusInc = 43, lightningResistBase = 44, lightningResistMaxBase = 5, }, + [24] = { auraRadiusInc = 44, lightningResistBase = 45, lightningResistMaxBase = 5, }, + [25] = { auraRadiusInc = 45, lightningResistBase = 46, lightningResistMaxBase = 5, }, + [26] = { auraRadiusInc = 46, lightningResistBase = 47, lightningResistMaxBase = 5, }, + [27] = { auraRadiusInc = 47, lightningResistBase = 48, lightningResistMaxBase = 5, }, + [28] = { auraRadiusInc = 48, lightningResistBase = 49, lightningResistMaxBase = 5, }, + [29] = { auraRadiusInc = 49, lightningResistBase = 50, lightningResistMaxBase = 5, }, + [30] = { auraRadiusInc = 50, lightningResistBase = 51, lightningResistMaxBase = 5, }, + } +} +gems["Raise Spectre"] = { + unsupported = true, +} +gems["Raise Zombie"] = { + unsupported = true, +} +gems["Righteous Fire"] = { + spell = true, + aoe = true, + fire = true, + setupFunc = function(mergeMod, output) + mergeMod("skill_fireDotBase", (output.total_life + output.total_energyShield) * 0.5) + end, + base = { + skill_dotIsDegen = true, + }, + quality = { + buff_spell_damageInc = 1, + }, + levels = { + [1] = { buff_spell_damageMore = 1.4, }, + [2] = { buff_spell_damageMore = 1.41, }, + [3] = { buff_spell_damageMore = 1.42, }, + [4] = { buff_spell_damageMore = 1.43, }, + [5] = { buff_spell_damageMore = 1.44, }, + [6] = { buff_spell_damageMore = 1.45, }, + [7] = { buff_spell_damageMore = 1.46, }, + [8] = { buff_spell_damageMore = 1.47, }, + [9] = { buff_spell_damageMore = 1.48, }, + [10] = { buff_spell_damageMore = 1.49, }, + [11] = { buff_spell_damageMore = 1.5, }, + [12] = { buff_spell_damageMore = 1.51, }, + [13] = { buff_spell_damageMore = 1.52, }, + [14] = { buff_spell_damageMore = 1.53, }, + [15] = { buff_spell_damageMore = 1.54, }, + [16] = { buff_spell_damageMore = 1.55, }, + [17] = { buff_spell_damageMore = 1.56, }, + [18] = { buff_spell_damageMore = 1.57, }, + [19] = { buff_spell_damageMore = 1.58, }, + [20] = { buff_spell_damageMore = 1.59, }, + [21] = { buff_spell_damageMore = 1.6, }, + [22] = { buff_spell_damageMore = 1.61, }, + [23] = { buff_spell_damageMore = 1.62, }, + [24] = { buff_spell_damageMore = 1.63, }, + [25] = { buff_spell_damageMore = 1.64, }, + [26] = { buff_spell_damageMore = 1.65, }, + [27] = { buff_spell_damageMore = 1.66, }, + [28] = { buff_spell_damageMore = 1.67, }, + [29] = { buff_spell_damageMore = 1.68, }, + [30] = { buff_spell_damageMore = 1.69, }, + } +} +gems["Shock Nova"] = { + spell = true, + aoe = true, + lightning = true, + parts = { + { + name = "Ring", + }, + { + name = "Nova", + }, + }, + base = { + skill_castTime = 0.75, + skill_damageEff = 0.6, + skill_critChanceBase = 6, + part1_spell_damageMore = 0.5, + shockChance = 20, + }, + quality = { + shock_durationInc = 2, + }, + levels = { + [1] = { skill_manaCostBase = 13, skill_lightningMin = 20, skill_lightningMax = 59, }, + [2] = { skill_manaCostBase = 14, skill_lightningMin = 24, skill_lightningMax = 71, }, + [3] = { skill_manaCostBase = 15, skill_lightningMin = 28, skill_lightningMax = 84, }, + [4] = { skill_manaCostBase = 16, skill_lightningMin = 33, skill_lightningMax = 100, }, + [5] = { skill_manaCostBase = 17, skill_lightningMin = 40, skill_lightningMax = 119, }, + [6] = { skill_manaCostBase = 18, skill_lightningMin = 44, skill_lightningMax = 133, }, + [7] = { skill_manaCostBase = 18, skill_lightningMin = 49, skill_lightningMax = 148, }, + [8] = { skill_manaCostBase = 19, skill_lightningMin = 55, skill_lightningMax = 165, }, + [9] = { skill_manaCostBase = 19, skill_lightningMin = 61, skill_lightningMax = 184, }, + [10] = { skill_manaCostBase = 20, skill_lightningMin = 68, skill_lightningMax = 204, }, + [11] = { skill_manaCostBase = 20, skill_lightningMin = 75, skill_lightningMax = 226, }, + [12] = { skill_manaCostBase = 21, skill_lightningMin = 84, skill_lightningMax = 251, }, + [13] = { skill_manaCostBase = 22, skill_lightningMin = 93, skill_lightningMax = 278, }, + [14] = { skill_manaCostBase = 22, skill_lightningMin = 103, skill_lightningMax = 308, }, + [15] = { skill_manaCostBase = 23, skill_lightningMin = 113, skill_lightningMax = 340, }, + [16] = { skill_manaCostBase = 23, skill_lightningMin = 125, skill_lightningMax = 376, }, + [17] = { skill_manaCostBase = 24, skill_lightningMin = 138, skill_lightningMax = 415, }, + [18] = { skill_manaCostBase = 25, skill_lightningMin = 152, skill_lightningMax = 457, }, + [19] = { skill_manaCostBase = 25, skill_lightningMin = 168, skill_lightningMax = 504, }, + [20] = { skill_manaCostBase = 26, skill_lightningMin = 185, skill_lightningMax = 555, }, + [21] = { skill_manaCostBase = 26, skill_lightningMin = 204, skill_lightningMax = 611, }, + [22] = { skill_manaCostBase = 27, skill_lightningMin = 224, skill_lightningMax = 672, }, + [23] = { skill_manaCostBase = 28, skill_lightningMin = 246, skill_lightningMax = 739, }, + [24] = { skill_manaCostBase = 28, skill_lightningMin = 271, skill_lightningMax = 813, }, + [25] = { skill_manaCostBase = 29, skill_lightningMin = 298, skill_lightningMax = 893, }, + [26] = { skill_manaCostBase = 29, skill_lightningMin = 327, skill_lightningMax = 980, }, + [27] = { skill_manaCostBase = 30, skill_lightningMin = 358, skill_lightningMax = 1075, }, + [28] = { skill_manaCostBase = 31, skill_lightningMin = 393, skill_lightningMax = 1179, }, + [29] = { skill_manaCostBase = 31, skill_lightningMin = 431, skill_lightningMax = 1293, }, + [30] = { skill_manaCostBase = 32, skill_lightningMin = 472, skill_lightningMax = 1417, }, + } +} +gems["Spark"] = { + spell = true, + projectile = true, + duration = true, + lightning = true, + base = { + skill_castTime = 0.65, + skill_damageEff = 0.7, + skill_critChanceBase = 6, + skill_baseDur = 1.5, + }, + quality = { + projectileSpeedInc = 2, + }, + levels = { + [1] = { skill_manaCostBase = 5, skill_lightningMin = 1, skill_lightningMax = 20, }, + [2] = { skill_manaCostBase = 6, skill_lightningMin = 1, skill_lightningMax = 22, }, + [3] = { skill_manaCostBase = 7, skill_lightningMin = 1, skill_lightningMax = 27, }, + [4] = { skill_manaCostBase = 8, skill_lightningMin = 2, skill_lightningMax = 36, }, + [5] = { skill_manaCostBase = 9, skill_lightningMin = 3, skill_lightningMax = 49, }, + [6] = { skill_manaCostBase = 10, skill_lightningMin = 4, skill_lightningMax = 69, }, + [7] = { skill_manaCostBase = 11, skill_lightningMin = 5, skill_lightningMax = 88, }, + [8] = { skill_manaCostBase = 12, skill_lightningMin = 6, skill_lightningMax = 110, }, + [9] = { skill_manaCostBase = 14, skill_lightningMin = 7, skill_lightningMax = 136, }, + [10] = { skill_manaCostBase = 16, skill_lightningMin = 9, skill_lightningMax = 167, }, + [11] = { skill_manaCostBase = 17, skill_lightningMin = 11, skill_lightningMax = 202, }, + [12] = { skill_manaCostBase = 18, skill_lightningMin = 13, skill_lightningMax = 243, }, + [13] = { skill_manaCostBase = 19, skill_lightningMin = 15, skill_lightningMax = 291, }, + [14] = { skill_manaCostBase = 20, skill_lightningMin = 18, skill_lightningMax = 345, }, + [15] = { skill_manaCostBase = 21, skill_lightningMin = 22, skill_lightningMax = 409, }, + [16] = { skill_manaCostBase = 22, skill_lightningMin = 25, skill_lightningMax = 481, }, + [17] = { skill_manaCostBase = 22, skill_lightningMin = 30, skill_lightningMax = 565, }, + [18] = { skill_manaCostBase = 22, skill_lightningMin = 35, skill_lightningMax = 661, }, + [19] = { skill_manaCostBase = 22, skill_lightningMin = 39, skill_lightningMax = 742, }, + [20] = { skill_manaCostBase = 23, skill_lightningMin = 44, skill_lightningMax = 832, }, + [21] = { skill_manaCostBase = 23, skill_lightningMin = 47, skill_lightningMax = 897, }, + [22] = { skill_manaCostBase = 24, skill_lightningMin = 51, skill_lightningMax = 967, }, + [23] = { skill_manaCostBase = 24, skill_lightningMin = 55, skill_lightningMax = 1041, }, + [24] = { skill_manaCostBase = 25, skill_lightningMin = 59, skill_lightningMax = 1120, }, + [25] = { skill_manaCostBase = 25, skill_lightningMin = 63, skill_lightningMax = 1205, }, + [26] = { skill_manaCostBase = 26, skill_lightningMin = 68, skill_lightningMax = 1296, }, + [27] = { skill_manaCostBase = 26, skill_lightningMin = 73, skill_lightningMax = 1393, }, + [28] = { skill_manaCostBase = 26, skill_lightningMin = 79, skill_lightningMax = 1496, }, + [29] = { skill_manaCostBase = 26, skill_lightningMin = 85, skill_lightningMax = 1607, }, + [30] = { skill_manaCostBase = 27, skill_lightningMin = 91, skill_lightningMax = 1725, }, + } +} +gems["Storm Call"] = { + spell = true, + aoe = true, + duration = true, + lightning = true, + base = { + skill_castTime = 0.5, + skill_damageEff = 0.8, + skill_critChanceBase = 6, + skill_durationBase = 1.5, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { skill_manaCostBase = 6, skill_lightningMin = 13, skill_lightningMax = 24, }, + [2] = { skill_manaCostBase = 7, skill_lightningMin = 16, skill_lightningMax = 30, }, + [3] = { skill_manaCostBase = 8, skill_lightningMin = 22, skill_lightningMax = 40, }, + [4] = { skill_manaCostBase = 9, skill_lightningMin = 28, skill_lightningMax = 53, }, + [5] = { skill_manaCostBase = 10, skill_lightningMin = 37, skill_lightningMax = 68, }, + [6] = { skill_manaCostBase = 11, skill_lightningMin = 46, skill_lightningMax = 86, }, + [7] = { skill_manaCostBase = 12, skill_lightningMin = 58, skill_lightningMax = 108, }, + [8] = { skill_manaCostBase = 13, skill_lightningMin = 69, skill_lightningMax = 128, }, + [9] = { skill_manaCostBase = 13, skill_lightningMin = 81, skill_lightningMax = 151, }, + [10] = { skill_manaCostBase = 14, skill_lightningMin = 95, skill_lightningMax = 177, }, + [11] = { skill_manaCostBase = 14, skill_lightningMin = 111, skill_lightningMax = 206, }, + [12] = { skill_manaCostBase = 15, skill_lightningMin = 130, skill_lightningMax = 241, }, + [13] = { skill_manaCostBase = 16, skill_lightningMin = 151, skill_lightningMax = 280, }, + [14] = { skill_manaCostBase = 16, skill_lightningMin = 175, skill_lightningMax = 325, }, + [15] = { skill_manaCostBase = 17, skill_lightningMin = 202, skill_lightningMax = 376, }, + [16] = { skill_manaCostBase = 18, skill_lightningMin = 234, skill_lightningMax = 434, }, + [17] = { skill_manaCostBase = 18, skill_lightningMin = 257, skill_lightningMax = 478, }, + [18] = { skill_manaCostBase = 19, skill_lightningMin = 283, skill_lightningMax = 525, }, + [19] = { skill_manaCostBase = 19, skill_lightningMin = 310, skill_lightningMax = 577, }, + [20] = { skill_manaCostBase = 19, skill_lightningMin = 341, skill_lightningMax = 633, }, + [21] = { skill_manaCostBase = 20, skill_lightningMin = 374, skill_lightningMax = 694, }, + [22] = { skill_manaCostBase = 21, skill_lightningMin = 410, skill_lightningMax = 761, }, + [23] = { skill_manaCostBase = 21, skill_lightningMin = 449, skill_lightningMax = 834, }, + [24] = { skill_manaCostBase = 21, skill_lightningMin = 492, skill_lightningMax = 914, }, + [25] = { skill_manaCostBase = 22, skill_lightningMin = 538, skill_lightningMax = 1000, }, + [26] = { skill_manaCostBase = 23, skill_lightningMin = 589, skill_lightningMax = 1094, }, + [27] = { skill_manaCostBase = 23, skill_lightningMin = 644, skill_lightningMax = 1196, }, + [28] = { skill_manaCostBase = 23, skill_lightningMin = 704, skill_lightningMax = 1308, }, + [29] = { skill_manaCostBase = 24, skill_lightningMin = 769, skill_lightningMax = 1429, }, + [30] = { skill_manaCostBase = 24, skill_lightningMin = 840, skill_lightningMax = 1560, }, + } +} +gems["Summon Chaos Golem"] = { + unsupported = true, +} +gems["Summon Lightning Golem"] = { + spell = true, + minion = true, + golem = true, + lightning = true, + base = { + skill_castTime = 1, + }, + quality = { + minionLifeInc = 1, + minion_damageInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 30, minionLifeInc = 30, buff_speedInc = 6, }, + [2] = { skill_manaCostBase = 32, minionLifeInc = 32, buff_speedInc = 6, }, + [3] = { skill_manaCostBase = 34, minionLifeInc = 34, buff_speedInc = 6, }, + [4] = { skill_manaCostBase = 36, minionLifeInc = 36, buff_speedInc = 6, }, + [5] = { skill_manaCostBase = 38, minionLifeInc = 38, buff_speedInc = 6, }, + [6] = { skill_manaCostBase = 40, minionLifeInc = 40, buff_speedInc = 7, }, + [7] = { skill_manaCostBase = 42, minionLifeInc = 42, buff_speedInc = 7, }, + [8] = { skill_manaCostBase = 44, minionLifeInc = 44, buff_speedInc = 7, }, + [9] = { skill_manaCostBase = 44, minionLifeInc = 46, buff_speedInc = 7, }, + [10] = { skill_manaCostBase = 46, minionLifeInc = 48, buff_speedInc = 7, }, + [11] = { skill_manaCostBase = 48, minionLifeInc = 50, buff_speedInc = 8, }, + [12] = { skill_manaCostBase = 48, minionLifeInc = 52, buff_speedInc = 8, }, + [13] = { skill_manaCostBase = 50, minionLifeInc = 54, buff_speedInc = 8, }, + [14] = { skill_manaCostBase = 50, minionLifeInc = 56, buff_speedInc = 8, }, + [15] = { skill_manaCostBase = 52, minionLifeInc = 58, buff_speedInc = 8, }, + [16] = { skill_manaCostBase = 52, minionLifeInc = 60, buff_speedInc = 9, }, + [17] = { skill_manaCostBase = 52, minionLifeInc = 62, buff_speedInc = 9, }, + [18] = { skill_manaCostBase = 52, minionLifeInc = 64, buff_speedInc = 9, }, + [19] = { skill_manaCostBase = 54, minionLifeInc = 66, buff_speedInc = 9, }, + [20] = { skill_manaCostBase = 54, minionLifeInc = 68, buff_speedInc = 9, }, + [21] = { skill_manaCostBase = 56, minionLifeInc = 70, buff_speedInc = 10, }, + [22] = { skill_manaCostBase = 56, minionLifeInc = 72, buff_speedInc = 10, }, + [23] = { skill_manaCostBase = 58, minionLifeInc = 74, buff_speedInc = 10, }, + [24] = { skill_manaCostBase = 58, minionLifeInc = 76, buff_speedInc = 10, }, + [25] = { skill_manaCostBase = 60, minionLifeInc = 78, buff_speedInc = 10, }, + [26] = { skill_manaCostBase = 60, minionLifeInc = 80, buff_speedInc = 11, }, + [27] = { skill_manaCostBase = 60, minionLifeInc = 82, buff_speedInc = 11, }, + [28] = { skill_manaCostBase = 60, minionLifeInc = 84, buff_speedInc = 11, }, + [29] = { skill_manaCostBase = 62, minionLifeInc = 86, buff_speedInc = 11, }, + [30] = { skill_manaCostBase = 62, minionLifeInc = 88, buff_speedInc = 11, }, + } +} +gems["Summon Raging Spirit"] = { + unsupported = true, +} +gems["Summon Skeletons"] = { + unsupported = true, +} +gems["Tempest Shield"] = { + unsupported = true, +} +gems["Vulnerability"] = { + unsupported = true, +} +gems["Wither"] = { + unsupported = true, +} +gems["Wrath"] = { + aura = true, + spell = true, + aoe = true, + lightning = true, + base = { + skill_manaReservedPercent = 50, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { auraRadiusInc = 0, attack_lightningMin = 2, attack_lightningMax = 37, spell_lightningMore = 1.15, }, + [2] = { auraRadiusInc = 3, attack_lightningMin = 3, attack_lightningMax = 43, spell_lightningMore = 1.15, }, + [3] = { auraRadiusInc = 6, attack_lightningMin = 3, attack_lightningMax = 50, spell_lightningMore = 1.15, }, + [4] = { auraRadiusInc = 9, attack_lightningMin = 4, attack_lightningMax = 57, spell_lightningMore = 1.16, }, + [5] = { auraRadiusInc = 12, attack_lightningMin = 4, attack_lightningMax = 66, spell_lightningMore = 1.16, }, + [6] = { auraRadiusInc = 15, attack_lightningMin = 5, attack_lightningMax = 75, spell_lightningMore = 1.16, }, + [7] = { auraRadiusInc = 18, attack_lightningMin = 5, attack_lightningMax = 85, spell_lightningMore = 1.17, }, + [8] = { auraRadiusInc = 21, attack_lightningMin = 6, attack_lightningMax = 97, spell_lightningMore = 1.17, }, + [9] = { auraRadiusInc = 23, attack_lightningMin = 7, attack_lightningMax = 109, spell_lightningMore = 1.17, }, + [10] = { auraRadiusInc = 25, attack_lightningMin = 7, attack_lightningMax = 118, spell_lightningMore = 1.18, }, + [11] = { auraRadiusInc = 27, attack_lightningMin = 8, attack_lightningMax = 128, spell_lightningMore = 1.18, }, + [12] = { auraRadiusInc = 29, attack_lightningMin = 9, attack_lightningMax = 138, spell_lightningMore = 1.18, }, + [13] = { auraRadiusInc = 31, attack_lightningMin = 9, attack_lightningMax = 149, spell_lightningMore = 1.19, }, + [14] = { auraRadiusInc = 33, attack_lightningMin = 10, attack_lightningMax = 161, spell_lightningMore = 1.19, }, + [15] = { auraRadiusInc = 35, attack_lightningMin = 11, attack_lightningMax = 173, spell_lightningMore = 1.19, }, + [16] = { auraRadiusInc = 36, attack_lightningMin = 12, attack_lightningMax = 186, spell_lightningMore = 1.2, }, + [17] = { auraRadiusInc = 37, attack_lightningMin = 13, attack_lightningMax = 200, spell_lightningMore = 1.2, }, + [18] = { auraRadiusInc = 38, attack_lightningMin = 13, attack_lightningMax = 215, spell_lightningMore = 1.2, }, + [19] = { auraRadiusInc = 39, attack_lightningMin = 14, attack_lightningMax = 231, spell_lightningMore = 1.21, }, + [20] = { auraRadiusInc = 40, attack_lightningMin = 16, attack_lightningMax = 248, spell_lightningMore = 1.21, }, + [21] = { auraRadiusInc = 41, attack_lightningMin = 17, attack_lightningMax = 267, spell_lightningMore = 1.21, }, + [22] = { auraRadiusInc = 42, attack_lightningMin = 18, attack_lightningMax = 286, spell_lightningMore = 1.22, }, + [23] = { auraRadiusInc = 43, attack_lightningMin = 19, attack_lightningMax = 306, spell_lightningMore = 1.22, }, + [24] = { auraRadiusInc = 44, attack_lightningMin = 20, attack_lightningMax = 328, spell_lightningMore = 1.22, }, + [25] = { auraRadiusInc = 45, attack_lightningMin = 22, attack_lightningMax = 351, spell_lightningMore = 1.23, }, + [26] = { auraRadiusInc = 46, attack_lightningMin = 23, attack_lightningMax = 375, spell_lightningMore = 1.23, }, + [27] = { auraRadiusInc = 47, attack_lightningMin = 25, attack_lightningMax = 401, spell_lightningMore = 1.23, }, + [28] = { auraRadiusInc = 48, attack_lightningMin = 27, attack_lightningMax = 429, spell_lightningMore = 1.24, }, + [29] = { auraRadiusInc = 49, attack_lightningMin = 29, attack_lightningMax = 458, spell_lightningMore = 1.24, }, + [30] = { auraRadiusInc = 50, attack_lightningMin = 31, attack_lightningMax = 490, spell_lightningMore = 1.24, }, + } +} diff --git a/Gems/act_str.lua b/Gems/act_str.lua new file mode 100644 index 00000000..cfd9e602 --- /dev/null +++ b/Gems/act_str.lua @@ -0,0 +1,1134 @@ +local gems = ... + +gems["Abyssal Cry"] = { + unsupported = true, +} +gems["Ancestral Protector"] = { + attack = true, + melee = true, + totem = true, + duration = true, + base = { + skill_manaCostBase = 8, + skill_durationBase = 12, + totemPlacementSpeedInc = 50, + }, + quality = { + totem_damageInc = 1, + }, + levels = { + [1] = { attack_damageMore = 60, buff_attackSpeedMore = 1.1, }, + [2] = { attack_damageMore = 60.8, buff_attackSpeedMore = 1.11, }, + [3] = { attack_damageMore = 61.6, buff_attackSpeedMore = 1.11, }, + [4] = { attack_damageMore = 62.4, buff_attackSpeedMore = 1.12, }, + [5] = { attack_damageMore = 63.2, buff_attackSpeedMore = 1.12, }, + [6] = { attack_damageMore = 64, buff_attackSpeedMore = 1.13, }, + [7] = { attack_damageMore = 64.8, buff_attackSpeedMore = 1.13, }, + [8] = { attack_damageMore = 65.6, buff_attackSpeedMore = 1.14, }, + [9] = { attack_damageMore = 66.4, buff_attackSpeedMore = 1.14, }, + [10] = { attack_damageMore = 67.2, buff_attackSpeedMore = 1.15, }, + [11] = { attack_damageMore = 68, buff_attackSpeedMore = 1.15, }, + [12] = { attack_damageMore = 68.8, buff_attackSpeedMore = 1.16, }, + [13] = { attack_damageMore = 69.6, buff_attackSpeedMore = 1.16, }, + [14] = { attack_damageMore = 70.4, buff_attackSpeedMore = 1.17, }, + [15] = { attack_damageMore = 71.2, buff_attackSpeedMore = 1.17, }, + [16] = { attack_damageMore = 72, buff_attackSpeedMore = 1.18, }, + [17] = { attack_damageMore = 72.8, buff_attackSpeedMore = 1.18, }, + [18] = { attack_damageMore = 73.6, buff_attackSpeedMore = 1.19, }, + [19] = { attack_damageMore = 74.4, buff_attackSpeedMore = 1.19, }, + [20] = { attack_damageMore = 75.2, buff_attackSpeedMore = 1.2, }, + [21] = { attack_damageMore = 76, buff_attackSpeedMore = 1.2, }, + [22] = { attack_damageMore = 76.8, buff_attackSpeedMore = 1.21, }, + [23] = { attack_damageMore = 77.6, buff_attackSpeedMore = 1.21, }, + [24] = { attack_damageMore = 78.4, buff_attackSpeedMore = 1.22, }, + [25] = { attack_damageMore = 79.2, buff_attackSpeedMore = 1.22, }, + [26] = { attack_damageMore = 80, buff_attackSpeedMore = 1.23, }, + [27] = { attack_damageMore = 80.8, buff_attackSpeedMore = 1.23, }, + [28] = { attack_damageMore = 81.6, buff_attackSpeedMore = 1.24, }, + [29] = { attack_damageMore = 82.4, buff_attackSpeedMore = 1.24, }, + [30] = { attack_damageMore = 83.2, buff_attackSpeedMore = 1.25, }, + } +} +gems["Anger"] = { + aura = true, + spell = true, + aoe = true, + fire = true, + base = { + skill_manaReservedPercent = 50, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { attack_fireMin = 12, attack_fireMax = 21, auraRadiusInc = 0, spell_fireMin = 10, spell_fireMax = 16, }, + [2] = { attack_fireMin = 14, attack_fireMax = 24, auraRadiusInc = 3, spell_fireMin = 12, spell_fireMax = 19, }, + [3] = { attack_fireMin = 17, attack_fireMax = 28, auraRadiusInc = 6, spell_fireMin = 14, spell_fireMax = 22, }, + [4] = { attack_fireMin = 19, attack_fireMax = 32, auraRadiusInc = 9, spell_fireMin = 16, spell_fireMax = 26, }, + [5] = { attack_fireMin = 22, attack_fireMax = 37, auraRadiusInc = 12, spell_fireMin = 18, spell_fireMax = 29, }, + [6] = { attack_fireMin = 25, attack_fireMax = 42, auraRadiusInc = 15, spell_fireMin = 21, spell_fireMax = 33, }, + [7] = { attack_fireMin = 28, attack_fireMax = 47, auraRadiusInc = 18, spell_fireMin = 24, spell_fireMax = 38, }, + [8] = { attack_fireMin = 32, attack_fireMax = 54, auraRadiusInc = 21, spell_fireMin = 27, spell_fireMax = 43, }, + [9] = { attack_fireMin = 36, attack_fireMax = 61, auraRadiusInc = 23, spell_fireMin = 30, spell_fireMax = 48, }, + [10] = { attack_fireMin = 39, attack_fireMax = 66, auraRadiusInc = 25, spell_fireMin = 33, spell_fireMax = 53, }, + [11] = { attack_fireMin = 43, attack_fireMax = 71, auraRadiusInc = 27, spell_fireMin = 35, spell_fireMax = 57, }, + [12] = { attack_fireMin = 46, attack_fireMax = 77, auraRadiusInc = 29, spell_fireMin = 38, spell_fireMax = 61, }, + [13] = { attack_fireMin = 50, attack_fireMax = 83, auraRadiusInc = 31, spell_fireMin = 41, spell_fireMax = 66, }, + [14] = { attack_fireMin = 54, attack_fireMax = 89, auraRadiusInc = 33, spell_fireMin = 45, spell_fireMax = 71, }, + [15] = { attack_fireMin = 58, attack_fireMax = 96, auraRadiusInc = 35, spell_fireMin = 48, spell_fireMax = 77, }, + [16] = { attack_fireMin = 62, attack_fireMax = 104, auraRadiusInc = 36, spell_fireMin = 52, spell_fireMax = 83, }, + [17] = { attack_fireMin = 67, attack_fireMax = 111, auraRadiusInc = 37, spell_fireMin = 56, spell_fireMax = 89, }, + [18] = { attack_fireMin = 72, attack_fireMax = 120, auraRadiusInc = 38, spell_fireMin = 60, spell_fireMax = 96, }, + [19] = { attack_fireMin = 77, attack_fireMax = 129, auraRadiusInc = 39, spell_fireMin = 64, spell_fireMax = 103, }, + [20] = { attack_fireMin = 83, attack_fireMax = 138, auraRadiusInc = 40, spell_fireMin = 69, spell_fireMax = 110, }, + [21] = { attack_fireMin = 89, attack_fireMax = 148, auraRadiusInc = 41, spell_fireMin = 74, spell_fireMax = 118, }, + [22] = { attack_fireMin = 95, attack_fireMax = 159, auraRadiusInc = 42, spell_fireMin = 79, spell_fireMax = 127, }, + [23] = { attack_fireMin = 102, attack_fireMax = 170, auraRadiusInc = 43, spell_fireMin = 85, spell_fireMax = 136, }, + [24] = { attack_fireMin = 109, attack_fireMax = 182, auraRadiusInc = 44, spell_fireMin = 91, spell_fireMax = 146, }, + [25] = { attack_fireMin = 117, attack_fireMax = 195, auraRadiusInc = 45, spell_fireMin = 97, spell_fireMax = 156, }, + [26] = { attack_fireMin = 125, attack_fireMax = 209, auraRadiusInc = 46, spell_fireMin = 104, spell_fireMax = 167, }, + [27] = { attack_fireMin = 134, attack_fireMax = 223, auraRadiusInc = 47, spell_fireMin = 112, spell_fireMax = 178, }, + [28] = { attack_fireMin = 143, attack_fireMax = 238, auraRadiusInc = 48, spell_fireMin = 119, spell_fireMax = 191, }, + [29] = { attack_fireMin = 153, attack_fireMax = 255, auraRadiusInc = 49, spell_fireMin = 127, spell_fireMax = 204, }, + [30] = { attack_fireMin = 163, attack_fireMax = 272, auraRadiusInc = 50, spell_fireMin = 136, spell_fireMax = 218, }, + } +} +gems["Cleave"] = { + unsupported = true, +} +gems["Decoy Totem"] = { + unsupported = true, +} +gems["Determination"] = { + aura = true, + spell = true, + aoe = true, + base = { + skill_manaReservedPercent = 50, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { armourMore = 1.32, auraRadiusInc = 0, }, + [2] = { armourMore = 1.33, auraRadiusInc = 3, }, + [3] = { armourMore = 1.34, auraRadiusInc = 6, }, + [4] = { armourMore = 1.35, auraRadiusInc = 9, }, + [5] = { armourMore = 1.36, auraRadiusInc = 12, }, + [6] = { armourMore = 1.37, auraRadiusInc = 15, }, + [7] = { armourMore = 1.38, auraRadiusInc = 18, }, + [8] = { armourMore = 1.39, auraRadiusInc = 21, }, + [9] = { armourMore = 1.4, auraRadiusInc = 23, }, + [10] = { armourMore = 1.41, auraRadiusInc = 25, }, + [11] = { armourMore = 1.42, auraRadiusInc = 27, }, + [12] = { armourMore = 1.43, auraRadiusInc = 29, }, + [13] = { armourMore = 1.44, auraRadiusInc = 31, }, + [14] = { armourMore = 1.45, auraRadiusInc = 33, }, + [15] = { armourMore = 1.46, auraRadiusInc = 35, }, + [16] = { armourMore = 1.47, auraRadiusInc = 36, }, + [17] = { armourMore = 1.48, auraRadiusInc = 37, }, + [18] = { armourMore = 1.49, auraRadiusInc = 38, }, + [19] = { armourMore = 1.5, auraRadiusInc = 39, }, + [20] = { armourMore = 1.51, auraRadiusInc = 40, }, + [21] = { armourMore = 1.52, auraRadiusInc = 41, }, + [22] = { armourMore = 1.53, auraRadiusInc = 42, }, + [23] = { armourMore = 1.54, auraRadiusInc = 43, }, + [24] = { armourMore = 1.55, auraRadiusInc = 44, }, + [25] = { armourMore = 1.56, auraRadiusInc = 45, }, + [26] = { armourMore = 1.57, auraRadiusInc = 46, }, + [27] = { armourMore = 1.58, auraRadiusInc = 47, }, + [28] = { armourMore = 1.59, auraRadiusInc = 48, }, + [29] = { armourMore = 1.6, auraRadiusInc = 49, }, + [30] = { armourMore = 1.61, auraRadiusInc = 50, }, + } +} +gems["Devouring Totem"] = { + unsupported = true, +} +gems["Dominating Blow"] = { + unsupported = true, +} +gems["Earthquake"] = { + attack = true, + melee = true, + aoe = true, + duration = true, + parts = { + { + name = "Initial impact", + }, + { + name = "Aftershock", + }, + }, + base = { + skill_manaCostBase = 6, + skill_durationBase = 1.5, + }, + quality = { + physicalInc = 1, + }, + levels = { + [1] = { attack_damageMore = 0.9, part2_damageMore = 1.6, }, + [2] = { attack_damageMore = 0.91, part2_damageMore = 1.61, }, + [3] = { attack_damageMore = 0.92, part2_damageMore = 1.62, }, + [4] = { attack_damageMore = 0.93, part2_damageMore = 1.63, }, + [5] = { attack_damageMore = 0.94, part2_damageMore = 1.64, }, + [6] = { attack_damageMore = 0.95, part2_damageMore = 1.65, }, + [7] = { attack_damageMore = 0.96, part2_damageMore = 1.66, }, + [8] = { attack_damageMore = 0.97, part2_damageMore = 1.67, }, + [9] = { attack_damageMore = 0.98, part2_damageMore = 1.68, }, + [10] = { attack_damageMore = 0.99, part2_damageMore = 1.69, }, + [11] = { attack_damageMore = 1, part2_damageMore = 1.7, }, + [12] = { attack_damageMore = 1.01, part2_damageMore = 1.71, }, + [13] = { attack_damageMore = 1.02, part2_damageMore = 1.72, }, + [14] = { attack_damageMore = 1.03, part2_damageMore = 1.73, }, + [15] = { attack_damageMore = 1.04, part2_damageMore = 1.74, }, + [16] = { attack_damageMore = 1.05, part2_damageMore = 1.75, }, + [17] = { attack_damageMore = 1.06, part2_damageMore = 1.76, }, + [18] = { attack_damageMore = 1.07, part2_damageMore = 1.77, }, + [19] = { attack_damageMore = 1.08, part2_damageMore = 1.78, }, + [20] = { attack_damageMore = 1.09, part2_damageMore = 1.79, }, + [21] = { attack_damageMore = 1.1, part2_damageMore = 1.8, }, + [22] = { attack_damageMore = 1.11, part2_damageMore = 1.81, }, + [23] = { attack_damageMore = 1.12, part2_damageMore = 1.82, }, + [24] = { attack_damageMore = 1.13, part2_damageMore = 1.83, }, + [25] = { attack_damageMore = 1.14, part2_damageMore = 1.84, }, + [26] = { attack_damageMore = 1.15, part2_damageMore = 1.85, }, + [27] = { attack_damageMore = 1.16, part2_damageMore = 1.86, }, + [28] = { attack_damageMore = 1.17, part2_damageMore = 1.87, }, + [29] = { attack_damageMore = 1.18, part2_damageMore = 1.88, }, + [30] = { attack_damageMore = 1.19, part2_damageMore = 1.89, }, + } +} +gems["Enduring Cry"] = { + unsupported = true, +} +gems["Flame Totem"] = { + spell = true, + totem = true, + projectile = true, + duration = true, + fire = true, + base = { + skill_castTime = 0.25, + skill_damageEff = 0.25, + skill_critChanceBase = 5, + skill_durationBase = 8, + }, + quality = { + totemLifeInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 12, skill_fireMin = 1, skill_fireMax = 2, }, + [2] = { skill_manaCostBase = 14, skill_fireMin = 1, skill_fireMax = 3, }, + [3] = { skill_manaCostBase = 16, skill_fireMin = 2, skill_fireMax = 4, }, + [4] = { skill_manaCostBase = 17, skill_fireMin = 3, skill_fireMax = 5, }, + [5] = { skill_manaCostBase = 19, skill_fireMin = 4, skill_fireMax = 7, }, + [6] = { skill_manaCostBase = 21, skill_fireMin = 6, skill_fireMax = 10, }, + [7] = { skill_manaCostBase = 23, skill_fireMin = 9, skill_fireMax = 13, }, + [8] = { skill_manaCostBase = 24, skill_fireMin = 11, skill_fireMax = 17, }, + [9] = { skill_manaCostBase = 26, skill_fireMin = 14, skill_fireMax = 22, }, + [10] = { skill_manaCostBase = 29, skill_fireMin = 18, skill_fireMax = 28, }, + [11] = { skill_manaCostBase = 31, skill_fireMin = 24, skill_fireMax = 35, }, + [12] = { skill_manaCostBase = 32, skill_fireMin = 30, skill_fireMax = 45, }, + [13] = { skill_manaCostBase = 33, skill_fireMin = 37, skill_fireMax = 56, }, + [14] = { skill_manaCostBase = 34, skill_fireMin = 47, skill_fireMax = 70, }, + [15] = { skill_manaCostBase = 36, skill_fireMin = 55, skill_fireMax = 83, }, + [16] = { skill_manaCostBase = 37, skill_fireMin = 65, skill_fireMax = 97, }, + [17] = { skill_manaCostBase = 39, skill_fireMin = 76, skill_fireMax = 114, }, + [18] = { skill_manaCostBase = 40, skill_fireMin = 89, skill_fireMax = 134, }, + [19] = { skill_manaCostBase = 41, skill_fireMin = 105, skill_fireMax = 157, }, + [20] = { skill_manaCostBase = 42, skill_fireMin = 122, skill_fireMax = 183, }, + [21] = { skill_manaCostBase = 43, skill_fireMin = 136, skill_fireMax = 203, }, + [22] = { skill_manaCostBase = 44, skill_fireMin = 150, skill_fireMax = 225, }, + [23] = { skill_manaCostBase = 45, skill_fireMin = 166, skill_fireMax = 249, }, + [24] = { skill_manaCostBase = 46, skill_fireMin = 184, skill_fireMax = 276, }, + [25] = { skill_manaCostBase = 47, skill_fireMin = 204, skill_fireMax = 305, }, + [26] = { skill_manaCostBase = 48, skill_fireMin = 225, skill_fireMax = 338, }, + [27] = { skill_manaCostBase = 49, skill_fireMin = 249, skill_fireMax = 373, }, + [28] = { skill_manaCostBase = 50, skill_fireMin = 275, skill_fireMax = 412, }, + [29] = { skill_manaCostBase = 51, skill_fireMin = 303, skill_fireMax = 455, }, + [30] = { skill_manaCostBase = 52, skill_fireMin = 335, skill_fireMax = 502, }, + } +} +gems["Glacial Hammer"] = { + attack = true, + melee = true, + cold = true, + base = { + skill_manaCostBase = 5, + physicalConvertTocold = 50, + }, + quality = { + chill_durationInc = 2, + freeze_durationInc = 1, + }, + levels = { + [1] = { attack_damageMore = 1.4, }, + [2] = { attack_damageMore = 1.416, }, + [3] = { attack_damageMore = 1.432, }, + [4] = { attack_damageMore = 1.448, }, + [5] = { attack_damageMore = 1.464, }, + [6] = { attack_damageMore = 1.48, }, + [7] = { attack_damageMore = 1.496, }, + [8] = { attack_damageMore = 1.512, }, + [9] = { attack_damageMore = 1.528, }, + [10] = { attack_damageMore = 1.544, }, + [11] = { attack_damageMore = 1.56, }, + [12] = { attack_damageMore = 1.576, }, + [13] = { attack_damageMore = 1.592, }, + [14] = { attack_damageMore = 1.608, }, + [15] = { attack_damageMore = 1.624, }, + [16] = { attack_damageMore = 1.64, }, + [17] = { attack_damageMore = 1.656, }, + [18] = { attack_damageMore = 1.672, }, + [19] = { attack_damageMore = 1.688, }, + [20] = { attack_damageMore = 1.704, }, + [21] = { attack_damageMore = 1.72, }, + [22] = { attack_damageMore = 1.736, }, + [23] = { attack_damageMore = 1.752, }, + [24] = { attack_damageMore = 1.768, }, + [25] = { attack_damageMore = 1.784, }, + [26] = { attack_damageMore = 1.8, }, + [27] = { attack_damageMore = 1.816, }, + [28] = { attack_damageMore = 1.832, }, + [29] = { attack_damageMore = 1.848, }, + [30] = { attack_damageMore = 1.864, }, + } +} +gems["Ground Slam"] = { + attack = true, + melee = true, + aoe = true, + base = { + skill_manaCostBase = 6, + stunEnemyThreshInc = -25, + }, + quality = { + stunEnemyDurInc = 1.5, + }, + levels = { + [1] = { attack_damageMore = 0.85, aoeRadiusInc = 0, }, + [2] = { attack_damageMore = 0.86, aoeRadiusInc = 1, }, + [3] = { attack_damageMore = 0.87, aoeRadiusInc = 2, }, + [4] = { attack_damageMore = 0.88, aoeRadiusInc = 3, }, + [5] = { attack_damageMore = 0.89, aoeRadiusInc = 4, }, + [6] = { attack_damageMore = 0.9, aoeRadiusInc = 5, }, + [7] = { attack_damageMore = 0.91, aoeRadiusInc = 6, }, + [8] = { attack_damageMore = 0.92, aoeRadiusInc = 7, }, + [9] = { attack_damageMore = 0.93, aoeRadiusInc = 8, }, + [10] = { attack_damageMore = 0.94, aoeRadiusInc = 9, }, + [11] = { attack_damageMore = 0.95, aoeRadiusInc = 10, }, + [12] = { attack_damageMore = 0.96, aoeRadiusInc = 11, }, + [13] = { attack_damageMore = 0.97, aoeRadiusInc = 12, }, + [14] = { attack_damageMore = 0.98, aoeRadiusInc = 13, }, + [15] = { attack_damageMore = 0.99, aoeRadiusInc = 14, }, + [16] = { attack_damageMore = 1, aoeRadiusInc = 15, }, + [17] = { attack_damageMore = 1.01, aoeRadiusInc = 16, }, + [18] = { attack_damageMore = 1.02, aoeRadiusInc = 17, }, + [19] = { attack_damageMore = 1.03, aoeRadiusInc = 18, }, + [20] = { attack_damageMore = 1.04, aoeRadiusInc = 19, }, + [21] = { attack_damageMore = 1.05, aoeRadiusInc = 20, }, + [22] = { attack_damageMore = 1.06, aoeRadiusInc = 21, }, + [23] = { attack_damageMore = 1.07, aoeRadiusInc = 22, }, + [24] = { attack_damageMore = 1.08, aoeRadiusInc = 23, }, + [25] = { attack_damageMore = 1.09, aoeRadiusInc = 24, }, + [26] = { attack_damageMore = 1.1, aoeRadiusInc = 25, }, + [27] = { attack_damageMore = 1.11, aoeRadiusInc = 26, }, + [28] = { attack_damageMore = 1.12, aoeRadiusInc = 27, }, + [29] = { attack_damageMore = 1.13, aoeRadiusInc = 28, }, + [30] = { attack_damageMore = 1.14, aoeRadiusInc = 29, }, + } +} +gems["Heavy Strike"] = { + attack = true, + melee = true, + base = { + skill_manaCostBase = 5, + stunEnemyThreshInc = -25, + }, + quality = { + stunEnemyDurInc = 1, + }, + levels = { + [1] = { attack_damageMore = 1.5, }, + [2] = { attack_damageMore = 1.518, }, + [3] = { attack_damageMore = 1.536, }, + [4] = { attack_damageMore = 1.554, }, + [5] = { attack_damageMore = 1.572, }, + [6] = { attack_damageMore = 1.59, }, + [7] = { attack_damageMore = 1.608, }, + [8] = { attack_damageMore = 1.626, }, + [9] = { attack_damageMore = 1.644, }, + [10] = { attack_damageMore = 1.662, }, + [11] = { attack_damageMore = 1.68, }, + [12] = { attack_damageMore = 1.698, }, + [13] = { attack_damageMore = 1.716, }, + [14] = { attack_damageMore = 1.734, }, + [15] = { attack_damageMore = 1.752, }, + [16] = { attack_damageMore = 1.77, }, + [17] = { attack_damageMore = 1.788, }, + [18] = { attack_damageMore = 1.806, }, + [19] = { attack_damageMore = 1.824, }, + [20] = { attack_damageMore = 1.842, }, + [21] = { attack_damageMore = 1.86, }, + [22] = { attack_damageMore = 1.878, }, + [23] = { attack_damageMore = 1.896, }, + [24] = { attack_damageMore = 1.914, }, + [25] = { attack_damageMore = 1.932, }, + [26] = { attack_damageMore = 1.95, }, + [27] = { attack_damageMore = 1.968, }, + [28] = { attack_damageMore = 1.986, }, + [29] = { attack_damageMore = 2.004, }, + [30] = { attack_damageMore = 2.022, }, + } +} +gems["Herald of Ash"] = { + spell = true, + aoe = true, + fire = true, + base = { + skill_manaReservedPercent = 25, + buff_physicalGainAsfire = 15, + }, + quality = { + buff_fireInc = 0.75, + }, + levels = { + [1] = { }, + [2] = { }, + [3] = { }, + [4] = { }, + [5] = { }, + [6] = { }, + [7] = { }, + [8] = { }, + [9] = { }, + [10] = { }, + [11] = { }, + [12] = { }, + [13] = { }, + [14] = { }, + [15] = { }, + [16] = { }, + [17] = { }, + [18] = { }, + [19] = { }, + [20] = { }, + [21] = { }, + [22] = { }, + [23] = { }, + [24] = { }, + [25] = { }, + [26] = { }, + [27] = { }, + [28] = { }, + [29] = { }, + [30] = { }, + } +} +gems["Ice Crash"] = { + attack = true, + melee = true, + aoe = true, + cold = true, + parts = { + { + name = "First Hit", + }, + { + name = "Second Hit", + }, + { + name = "Third Hit", + }, + }, + base = { + skill_manaCostBase = 8, + physicalConvertTocold = 50, + attackSpeedMore = 0.75, + part2_damageMore = 0.8, + part3_damageMore = 0.6, + }, + quality = { + coldInc = 1, + }, + levels = { + [1] = { attack_damageMore = 1.5, }, + [2] = { attack_damageMore = 1.518, }, + [3] = { attack_damageMore = 1.536, }, + [4] = { attack_damageMore = 1.554, }, + [5] = { attack_damageMore = 1.572, }, + [6] = { attack_damageMore = 1.59, }, + [7] = { attack_damageMore = 1.608, }, + [8] = { attack_damageMore = 1.626, }, + [9] = { attack_damageMore = 1.644, }, + [10] = { attack_damageMore = 1.662, }, + [11] = { attack_damageMore = 1.68, }, + [12] = { attack_damageMore = 1.698, }, + [13] = { attack_damageMore = 1.716, }, + [14] = { attack_damageMore = 1.734, }, + [15] = { attack_damageMore = 1.752, }, + [16] = { attack_damageMore = 1.77, }, + [17] = { attack_damageMore = 1.788, }, + [18] = { attack_damageMore = 1.806, }, + [19] = { attack_damageMore = 1.824, }, + [20] = { attack_damageMore = 1.842, }, + [21] = { attack_damageMore = 1.86, }, + [22] = { attack_damageMore = 1.878, }, + [23] = { attack_damageMore = 1.896, }, + [24] = { attack_damageMore = 1.914, }, + [25] = { attack_damageMore = 1.932, }, + [26] = { attack_damageMore = 1.95, }, + [27] = { attack_damageMore = 1.968, }, + [28] = { attack_damageMore = 1.986, }, + [29] = { attack_damageMore = 2.004, }, + [30] = { attack_damageMore = 2.022, }, + } +} +gems["Immortal Call"] = { + unsupported = true, +} +gems["Infernal Blow"] = { + attack = true, + melee = true, + aoe = true, + fire = true, + base = { + skill_manaCostBase = 6, + physicalConvertTofire = 50, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { attack_damageMore = 1.3, }, + [2] = { attack_damageMore = 1.316, }, + [3] = { attack_damageMore = 1.332, }, + [4] = { attack_damageMore = 1.348, }, + [5] = { attack_damageMore = 1.364, }, + [6] = { attack_damageMore = 1.38, }, + [7] = { attack_damageMore = 1.396, }, + [8] = { attack_damageMore = 1.412, }, + [9] = { attack_damageMore = 1.428, }, + [10] = { attack_damageMore = 1.444, }, + [11] = { attack_damageMore = 1.46, }, + [12] = { attack_damageMore = 1.476, }, + [13] = { attack_damageMore = 1.492, }, + [14] = { attack_damageMore = 1.508, }, + [15] = { attack_damageMore = 1.524, }, + [16] = { attack_damageMore = 1.54, }, + [17] = { attack_damageMore = 1.556, }, + [18] = { attack_damageMore = 1.572, }, + [19] = { attack_damageMore = 1.588, }, + [20] = { attack_damageMore = 1.604, }, + [21] = { attack_damageMore = 1.62, }, + [22] = { attack_damageMore = 1.636, }, + [23] = { attack_damageMore = 1.652, }, + [24] = { attack_damageMore = 1.668, }, + [25] = { attack_damageMore = 1.684, }, + [26] = { attack_damageMore = 1.7, }, + [27] = { attack_damageMore = 1.716, }, + [28] = { attack_damageMore = 1.732, }, + [29] = { attack_damageMore = 1.748, }, + [30] = { attack_damageMore = 1.764, }, + } +} +gems["Leap Slam"] = { + unsupported = true, +} +gems["Molten Shell"] = { + unsupported = true, +} +gems["Molten Strike"] = { + attack = true, + melee = true, + projectile = true, + aoe = true, + fire = true, + parts = { + { + name = "Melee Hit", + melee = true, + projectile = false, + aoe = false, + }, + { + name = "Magma Balls", + melee = false, + projectile = true, + aoe = true, + }, + }, + base = { + skill_manaCostBase = 6, + physicalConvertTofire = 60, + part2_damageMore = 0.6, + }, + quality = { + fireInc = 1, + }, + levels = { + [1] = { attack_damageMore = 1.2, }, + [2] = { attack_damageMore = 1.214, }, + [3] = { attack_damageMore = 1.228, }, + [4] = { attack_damageMore = 1.242, }, + [5] = { attack_damageMore = 1.256, }, + [6] = { attack_damageMore = 1.27, }, + [7] = { attack_damageMore = 1.284, }, + [8] = { attack_damageMore = 1.298, }, + [9] = { attack_damageMore = 1.312, }, + [10] = { attack_damageMore = 1.326, }, + [11] = { attack_damageMore = 1.34, }, + [12] = { attack_damageMore = 1.354, }, + [13] = { attack_damageMore = 1.368, }, + [14] = { attack_damageMore = 1.382, }, + [15] = { attack_damageMore = 1.396, }, + [16] = { attack_damageMore = 1.41, }, + [17] = { attack_damageMore = 1.424, }, + [18] = { attack_damageMore = 1.438, }, + [19] = { attack_damageMore = 1.452, }, + [20] = { attack_damageMore = 1.466, }, + [21] = { attack_damageMore = 1.48, }, + [22] = { attack_damageMore = 1.494, }, + [23] = { attack_damageMore = 1.508, }, + [24] = { attack_damageMore = 1.522, }, + [25] = { attack_damageMore = 1.536, }, + [26] = { attack_damageMore = 1.55, }, + [27] = { attack_damageMore = 1.564, }, + [28] = { attack_damageMore = 1.578, }, + [29] = { attack_damageMore = 1.592, }, + [30] = { attack_damageMore = 1.606, }, + } +} +gems["Punishment"] = { + unsupported = true, +} +gems["Purity of Fire"] = { + aura = true, + spell = true, + aoe = true, + fire = true, + base = { + skill_manaReservedPercent = 35, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { auraRadiusInc = 0, fireResistBase = 22, fireResistMaxBase = 0, }, + [2] = { auraRadiusInc = 3, fireResistBase = 23, fireResistMaxBase = 0, }, + [3] = { auraRadiusInc = 6, fireResistBase = 24, fireResistMaxBase = 0, }, + [4] = { auraRadiusInc = 9, fireResistBase = 25, fireResistMaxBase = 0, }, + [5] = { auraRadiusInc = 12, fireResistBase = 26, fireResistMaxBase = 1, }, + [6] = { auraRadiusInc = 15, fireResistBase = 27, fireResistMaxBase = 1, }, + [7] = { auraRadiusInc = 18, fireResistBase = 28, fireResistMaxBase = 1, }, + [8] = { auraRadiusInc = 21, fireResistBase = 29, fireResistMaxBase = 1, }, + [9] = { auraRadiusInc = 23, fireResistBase = 30, fireResistMaxBase = 1, }, + [10] = { auraRadiusInc = 25, fireResistBase = 31, fireResistMaxBase = 1, }, + [11] = { auraRadiusInc = 27, fireResistBase = 32, fireResistMaxBase = 2, }, + [12] = { auraRadiusInc = 29, fireResistBase = 33, fireResistMaxBase = 2, }, + [13] = { auraRadiusInc = 31, fireResistBase = 34, fireResistMaxBase = 2, }, + [14] = { auraRadiusInc = 33, fireResistBase = 35, fireResistMaxBase = 2, }, + [15] = { auraRadiusInc = 35, fireResistBase = 36, fireResistMaxBase = 2, }, + [16] = { auraRadiusInc = 36, fireResistBase = 37, fireResistMaxBase = 2, }, + [17] = { auraRadiusInc = 37, fireResistBase = 38, fireResistMaxBase = 3, }, + [18] = { auraRadiusInc = 38, fireResistBase = 39, fireResistMaxBase = 3, }, + [19] = { auraRadiusInc = 39, fireResistBase = 40, fireResistMaxBase = 3, }, + [20] = { auraRadiusInc = 40, fireResistBase = 41, fireResistMaxBase = 4, }, + [21] = { auraRadiusInc = 41, fireResistBase = 42, fireResistMaxBase = 4, }, + [22] = { auraRadiusInc = 42, fireResistBase = 43, fireResistMaxBase = 4, }, + [23] = { auraRadiusInc = 43, fireResistBase = 44, fireResistMaxBase = 5, }, + [24] = { auraRadiusInc = 44, fireResistBase = 45, fireResistMaxBase = 5, }, + [25] = { auraRadiusInc = 45, fireResistBase = 46, fireResistMaxBase = 5, }, + [26] = { auraRadiusInc = 46, fireResistBase = 47, fireResistMaxBase = 5, }, + [27] = { auraRadiusInc = 47, fireResistBase = 48, fireResistMaxBase = 5, }, + [28] = { auraRadiusInc = 48, fireResistBase = 49, fireResistMaxBase = 5, }, + [29] = { auraRadiusInc = 49, fireResistBase = 50, fireResistMaxBase = 5, }, + [30] = { auraRadiusInc = 50, fireResistBase = 51, fireResistMaxBase = 5, }, + } +} +gems["Rallying Cry"] = { + unsupported = true, +} +gems["Reckoning"] = { + unsupported = true, +} +gems["Rejuvenation Totem"] = { + unsupported = true, +} +gems["Searing Bond"] = { + spell = true, + totem = true, + duration = true, + fire = true, + base = { + skill_castTime = 1, + skill_durationBase = 8, + }, + quality = { + totemLifeInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 18, skill_fireDotBase = 23.6, }, + [2] = { skill_manaCostBase = 19, skill_fireDotBase = 31.4, }, + [3] = { skill_manaCostBase = 20, skill_fireDotBase = 44.8, }, + [4] = { skill_manaCostBase = 21, skill_fireDotBase = 62.8, }, + [5] = { skill_manaCostBase = 23, skill_fireDotBase = 86.8, }, + [6] = { skill_manaCostBase = 25, skill_fireDotBase = 118.4, }, + [7] = { skill_manaCostBase = 27, skill_fireDotBase = 160.1, }, + [8] = { skill_manaCostBase = 29, skill_fireDotBase = 199.6, }, + [9] = { skill_manaCostBase = 31, skill_fireDotBase = 247.9, }, + [10] = { skill_manaCostBase = 33, skill_fireDotBase = 306.8, }, + [11] = { skill_manaCostBase = 35, skill_fireDotBase = 378.5, }, + [12] = { skill_manaCostBase = 37, skill_fireDotBase = 465.6, }, + [13] = { skill_manaCostBase = 39, skill_fireDotBase = 571.5, }, + [14] = { skill_manaCostBase = 40, skill_fireDotBase = 699.7, }, + [15] = { skill_manaCostBase = 42, skill_fireDotBase = 854.9, }, + [16] = { skill_manaCostBase = 44, skill_fireDotBase = 1042.6, }, + [17] = { skill_manaCostBase = 46, skill_fireDotBase = 1189, }, + [18] = { skill_manaCostBase = 48, skill_fireDotBase = 1354.8, }, + [19] = { skill_manaCostBase = 50, skill_fireDotBase = 1542.8, }, + [20] = { skill_manaCostBase = 51, skill_fireDotBase = 1755.6, }, + [21] = { skill_manaCostBase = 53, skill_fireDotBase = 1996.6, }, + [22] = { skill_manaCostBase = 53, skill_fireDotBase = 2269.3, }, + [23] = { skill_manaCostBase = 54, skill_fireDotBase = 2577.7, }, + [24] = { skill_manaCostBase = 56, skill_fireDotBase = 2926.5, }, + [25] = { skill_manaCostBase = 58, skill_fireDotBase = 3320.8, }, + [26] = { skill_manaCostBase = 59, skill_fireDotBase = 3766.2, }, + [27] = { skill_manaCostBase = 59, skill_fireDotBase = 4269.5, }, + [28] = { skill_manaCostBase = 61, skill_fireDotBase = 4837.7, }, + [29] = { skill_manaCostBase = 62, skill_fireDotBase = 5479.2, }, + [30] = { skill_manaCostBase = 64, skill_fireDotBase = 6203.2, }, + } +} +gems["Shield Charge"] = { + attack = true, + melee = true, + movement = true, + base = { + skill_manaCostBase = 10, + attack_damageMore = 0.5, + }, + quality = { + damageInc = 1, + }, + levels = { + [1] = { movementSpeedInc = 50, damageMore = 3, }, + [2] = { movementSpeedInc = 51, damageMore = 3.12, }, + [3] = { movementSpeedInc = 52, damageMore = 3.24, }, + [4] = { movementSpeedInc = 53, damageMore = 3.36, }, + [5] = { movementSpeedInc = 54, damageMore = 3.48, }, + [6] = { movementSpeedInc = 55, damageMore = 3.6, }, + [7] = { movementSpeedInc = 56, damageMore = 3.72, }, + [8] = { movementSpeedInc = 57, damageMore = 3.84, }, + [9] = { movementSpeedInc = 58, damageMore = 3.96, }, + [10] = { movementSpeedInc = 59, damageMore = 4.08, }, + [11] = { movementSpeedInc = 60, damageMore = 4.2, }, + [12] = { movementSpeedInc = 61, damageMore = 4.32, }, + [13] = { movementSpeedInc = 62, damageMore = 4.44, }, + [14] = { movementSpeedInc = 63, damageMore = 4.56, }, + [15] = { movementSpeedInc = 64, damageMore = 4.68, }, + [16] = { movementSpeedInc = 65, damageMore = 4.8, }, + [17] = { movementSpeedInc = 66, damageMore = 4.92, }, + [18] = { movementSpeedInc = 67, damageMore = 5.04, }, + [19] = { movementSpeedInc = 68, damageMore = 5.16, }, + [20] = { movementSpeedInc = 69, damageMore = 5.28, }, + [21] = { movementSpeedInc = 70, damageMore = 5.4, }, + [22] = { movementSpeedInc = 71, damageMore = 5.52, }, + [23] = { movementSpeedInc = 72, damageMore = 5.64, }, + [24] = { movementSpeedInc = 73, damageMore = 5.76, }, + [25] = { movementSpeedInc = 74, damageMore = 5.88, }, + [26] = { movementSpeedInc = 75, damageMore = 6, }, + [27] = { movementSpeedInc = 76, damageMore = 6.12, }, + [28] = { movementSpeedInc = 77, damageMore = 6.24, }, + [29] = { movementSpeedInc = 78, damageMore = 6.36, }, + [30] = { movementSpeedInc = 79, damageMore = 6.48, }, + } +} +gems["Shockwave Totem"] = { + spell = true, + totem = true, + aoe = true, + duration = true, + base = { + skill_castTime = 0.6, + skill_damageEff = 0.6, + skill_critChanceBase = 5, + skill_durationBase = 8, + }, + quality = { + totemLifeInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 24, skill_physicalMin = 23, skill_physicalMax = 46, }, + [2] = { skill_manaCostBase = 26, skill_physicalMin = 28, skill_physicalMax = 51, }, + [3] = { skill_manaCostBase = 28, skill_physicalMin = 33, skill_physicalMax = 62, }, + [4] = { skill_manaCostBase = 31, skill_physicalMin = 40, skill_physicalMax = 74, }, + [5] = { skill_manaCostBase = 33, skill_physicalMin = 47, skill_physicalMax = 88, }, + [6] = { skill_manaCostBase = 34, skill_physicalMin = 53, skill_physicalMax = 98, }, + [7] = { skill_manaCostBase = 36, skill_physicalMin = 59, skill_physicalMax = 110, }, + [8] = { skill_manaCostBase = 39, skill_physicalMin = 66, skill_physicalMax = 123, }, + [9] = { skill_manaCostBase = 43, skill_physicalMin = 74, skill_physicalMax = 137, }, + [10] = { skill_manaCostBase = 46, skill_physicalMin = 82, skill_physicalMax = 153, }, + [11] = { skill_manaCostBase = 49, skill_physicalMin = 92, skill_physicalMax = 170, }, + [12] = { skill_manaCostBase = 51, skill_physicalMin = 102, skill_physicalMax = 189, }, + [13] = { skill_manaCostBase = 53, skill_physicalMin = 113, skill_physicalMax = 210, }, + [14] = { skill_manaCostBase = 53, skill_physicalMin = 126, skill_physicalMax = 233, }, + [15] = { skill_manaCostBase = 55, skill_physicalMin = 139, skill_physicalMax = 259, }, + [16] = { skill_manaCostBase = 55, skill_physicalMin = 154, skill_physicalMax = 287, }, + [17] = { skill_manaCostBase = 57, skill_physicalMin = 171, skill_physicalMax = 318, }, + [18] = { skill_manaCostBase = 57, skill_physicalMin = 189, skill_physicalMax = 351, }, + [19] = { skill_manaCostBase = 58, skill_physicalMin = 209, skill_physicalMax = 389, }, + [20] = { skill_manaCostBase = 58, skill_physicalMin = 231, skill_physicalMax = 429, }, + [21] = { skill_manaCostBase = 59, skill_physicalMin = 255, skill_physicalMax = 474, }, + [22] = { skill_manaCostBase = 60, skill_physicalMin = 282, skill_physicalMax = 524, }, + [23] = { skill_manaCostBase = 61, skill_physicalMin = 311, skill_physicalMax = 578, }, + [24] = { skill_manaCostBase = 62, skill_physicalMin = 343, skill_physicalMax = 637, }, + [25] = { skill_manaCostBase = 62, skill_physicalMin = 378, skill_physicalMax = 702, }, + [26] = { skill_manaCostBase = 63, skill_physicalMin = 416, skill_physicalMax = 773, }, + [27] = { skill_manaCostBase = 64, skill_physicalMin = 458, skill_physicalMax = 851, }, + [28] = { skill_manaCostBase = 65, skill_physicalMin = 504, skill_physicalMax = 936, }, + [29] = { skill_manaCostBase = 66, skill_physicalMin = 555, skill_physicalMax = 1030, }, + [30] = { skill_manaCostBase = 66, skill_physicalMin = 610, skill_physicalMax = 1132, }, + } +} +gems["Static Strike"] = { + attack = true, + melee = true, + aoe = true, + duration = true, + lightning = true, + parts = { + { + name = "Melee hit", + aoe = false, + }, + { + name = "Explosion", + aoe = true, + }, + }, + base = { + skill_manaCostBase = 6, + skill_durationBase = 0.75, + physicalConvertTolightning = 60, + part2_damageMore = 0.6, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { attack_damageMore = 1.1, }, + [2] = { attack_damageMore = 1.114, }, + [3] = { attack_damageMore = 1.128, }, + [4] = { attack_damageMore = 1.142, }, + [5] = { attack_damageMore = 1.156, }, + [6] = { attack_damageMore = 1.17, }, + [7] = { attack_damageMore = 1.184, }, + [8] = { attack_damageMore = 1.198, }, + [9] = { attack_damageMore = 1.212, }, + [10] = { attack_damageMore = 1.226, }, + [11] = { attack_damageMore = 1.24, }, + [12] = { attack_damageMore = 1.254, }, + [13] = { attack_damageMore = 1.268, }, + [14] = { attack_damageMore = 1.282, }, + [15] = { attack_damageMore = 1.296, }, + [16] = { attack_damageMore = 1.31, }, + [17] = { attack_damageMore = 1.324, }, + [18] = { attack_damageMore = 1.338, }, + [19] = { attack_damageMore = 1.352, }, + [20] = { attack_damageMore = 1.366, }, + [21] = { attack_damageMore = 1.38, }, + [22] = { attack_damageMore = 1.394, }, + [23] = { attack_damageMore = 1.408, }, + [24] = { attack_damageMore = 1.422, }, + [25] = { attack_damageMore = 1.436, }, + [26] = { attack_damageMore = 1.45, }, + [27] = { attack_damageMore = 1.464, }, + [28] = { attack_damageMore = 1.478, }, + [29] = { attack_damageMore = 1.492, }, + [30] = { attack_damageMore = 1.506, }, + } +} +gems["Summon Flame Golem"] = { + spell = true, + minion = true, + golem = true, + fire = true, + base = { + skill_castTime = 1, + }, + quality = { + minionLifeInc = 1, + minion_damageInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 30, minionLifeInc = 30, buff_damageInc = 15, }, + [2] = { skill_manaCostBase = 32, minionLifeInc = 32, buff_damageInc = 15, }, + [3] = { skill_manaCostBase = 34, minionLifeInc = 34, buff_damageInc = 16, }, + [4] = { skill_manaCostBase = 36, minionLifeInc = 36, buff_damageInc = 16, }, + [5] = { skill_manaCostBase = 38, minionLifeInc = 38, buff_damageInc = 16, }, + [6] = { skill_manaCostBase = 40, minionLifeInc = 40, buff_damageInc = 16, }, + [7] = { skill_manaCostBase = 42, minionLifeInc = 42, buff_damageInc = 17, }, + [8] = { skill_manaCostBase = 44, minionLifeInc = 44, buff_damageInc = 17, }, + [9] = { skill_manaCostBase = 44, minionLifeInc = 46, buff_damageInc = 17, }, + [10] = { skill_manaCostBase = 46, minionLifeInc = 48, buff_damageInc = 17, }, + [11] = { skill_manaCostBase = 48, minionLifeInc = 50, buff_damageInc = 18, }, + [12] = { skill_manaCostBase = 48, minionLifeInc = 52, buff_damageInc = 18, }, + [13] = { skill_manaCostBase = 50, minionLifeInc = 54, buff_damageInc = 18, }, + [14] = { skill_manaCostBase = 50, minionLifeInc = 56, buff_damageInc = 18, }, + [15] = { skill_manaCostBase = 52, minionLifeInc = 58, buff_damageInc = 19, }, + [16] = { skill_manaCostBase = 52, minionLifeInc = 60, buff_damageInc = 19, }, + [17] = { skill_manaCostBase = 52, minionLifeInc = 62, buff_damageInc = 19, }, + [18] = { skill_manaCostBase = 52, minionLifeInc = 64, buff_damageInc = 19, }, + [19] = { skill_manaCostBase = 54, minionLifeInc = 66, buff_damageInc = 20, }, + [20] = { skill_manaCostBase = 54, minionLifeInc = 68, buff_damageInc = 20, }, + [21] = { skill_manaCostBase = 56, minionLifeInc = 70, buff_damageInc = 20, }, + [22] = { skill_manaCostBase = 56, minionLifeInc = 72, buff_damageInc = 20, }, + [23] = { skill_manaCostBase = 58, minionLifeInc = 74, buff_damageInc = 21, }, + [24] = { skill_manaCostBase = 58, minionLifeInc = 76, buff_damageInc = 21, }, + [25] = { skill_manaCostBase = 60, minionLifeInc = 78, buff_damageInc = 21, }, + [26] = { skill_manaCostBase = 60, minionLifeInc = 80, buff_damageInc = 21, }, + [27] = { skill_manaCostBase = 60, minionLifeInc = 82, buff_damageInc = 22, }, + [28] = { skill_manaCostBase = 60, minionLifeInc = 84, buff_damageInc = 22, }, + [29] = { skill_manaCostBase = 62, minionLifeInc = 86, buff_damageInc = 22, }, + [30] = { skill_manaCostBase = 62, minionLifeInc = 88, buff_damageInc = 22, }, + } +} +gems["Summon Stone Golem"] = { + spell = true, + minion = true, + golem = true, + base = { + skill_castTime = 1, + }, + quality = { + minionLifeInc = 1, + minion_damageInc = 1, + }, + levels = { + [1] = { skill_manaCostBase = 30, minionLifeInc = 30, buff_lifeRegenBase = 33, }, + [2] = { skill_manaCostBase = 32, minionLifeInc = 32, buff_lifeRegenBase = 36, }, + [3] = { skill_manaCostBase = 34, minionLifeInc = 34, buff_lifeRegenBase = 39, }, + [4] = { skill_manaCostBase = 36, minionLifeInc = 36, buff_lifeRegenBase = 42, }, + [5] = { skill_manaCostBase = 38, minionLifeInc = 38, buff_lifeRegenBase = 45, }, + [6] = { skill_manaCostBase = 40, minionLifeInc = 40, buff_lifeRegenBase = 49, }, + [7] = { skill_manaCostBase = 42, minionLifeInc = 42, buff_lifeRegenBase = 52, }, + [8] = { skill_manaCostBase = 44, minionLifeInc = 44, buff_lifeRegenBase = 56, }, + [9] = { skill_manaCostBase = 44, minionLifeInc = 46, buff_lifeRegenBase = 60, }, + [10] = { skill_manaCostBase = 46, minionLifeInc = 48, buff_lifeRegenBase = 64, }, + [11] = { skill_manaCostBase = 48, minionLifeInc = 50, buff_lifeRegenBase = 68, }, + [12] = { skill_manaCostBase = 48, minionLifeInc = 52, buff_lifeRegenBase = 72, }, + [13] = { skill_manaCostBase = 50, minionLifeInc = 54, buff_lifeRegenBase = 76, }, + [14] = { skill_manaCostBase = 50, minionLifeInc = 56, buff_lifeRegenBase = 81, }, + [15] = { skill_manaCostBase = 52, minionLifeInc = 58, buff_lifeRegenBase = 85, }, + [16] = { skill_manaCostBase = 52, minionLifeInc = 60, buff_lifeRegenBase = 90, }, + [17] = { skill_manaCostBase = 52, minionLifeInc = 62, buff_lifeRegenBase = 95, }, + [18] = { skill_manaCostBase = 52, minionLifeInc = 64, buff_lifeRegenBase = 100, }, + [19] = { skill_manaCostBase = 54, minionLifeInc = 66, buff_lifeRegenBase = 103, }, + [20] = { skill_manaCostBase = 54, minionLifeInc = 68, buff_lifeRegenBase = 105, }, + [21] = { skill_manaCostBase = 56, minionLifeInc = 70, buff_lifeRegenBase = 110, }, + [22] = { skill_manaCostBase = 56, minionLifeInc = 72, buff_lifeRegenBase = 116, }, + [23] = { skill_manaCostBase = 58, minionLifeInc = 74, buff_lifeRegenBase = 121, }, + [24] = { skill_manaCostBase = 58, minionLifeInc = 76, buff_lifeRegenBase = 127, }, + [25] = { skill_manaCostBase = 60, minionLifeInc = 78, buff_lifeRegenBase = 133, }, + [26] = { skill_manaCostBase = 60, minionLifeInc = 80, buff_lifeRegenBase = 139, }, + [27] = { skill_manaCostBase = 60, minionLifeInc = 82, buff_lifeRegenBase = 145, }, + [28] = { skill_manaCostBase = 60, minionLifeInc = 84, buff_lifeRegenBase = 151, }, + [29] = { skill_manaCostBase = 62, minionLifeInc = 86, buff_lifeRegenBase = 157, }, + [30] = { skill_manaCostBase = 62, minionLifeInc = 88, buff_lifeRegenBase = 164, }, + } +} +gems["Sunder"] = { + attack = true, + melee = true, + aoe = true, + parts = { + { + name = "Primary wave", + }, + { + name = "Shockwaves", + }, + }, + base = { + skill_manaCostBase = 8, + attackSpeedMore = 0.85, + part2_damageMore = 0.7, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { attack_damageMore = 1, }, + [2] = { attack_damageMore = 1.01, }, + [3] = { attack_damageMore = 1.02, }, + [4] = { attack_damageMore = 1.03, }, + [5] = { attack_damageMore = 1.04, }, + [6] = { attack_damageMore = 1.05, }, + [7] = { attack_damageMore = 1.06, }, + [8] = { attack_damageMore = 1.07, }, + [9] = { attack_damageMore = 1.08, }, + [10] = { attack_damageMore = 1.09, }, + [11] = { attack_damageMore = 1.1, }, + [12] = { attack_damageMore = 1.11, }, + [13] = { attack_damageMore = 1.12, }, + [14] = { attack_damageMore = 1.13, }, + [15] = { attack_damageMore = 1.14, }, + [16] = { attack_damageMore = 1.15, }, + [17] = { attack_damageMore = 1.16, }, + [18] = { attack_damageMore = 1.17, }, + [19] = { attack_damageMore = 1.18, }, + [20] = { attack_damageMore = 1.19, }, + [21] = { attack_damageMore = 1.2, }, + [22] = { attack_damageMore = 1.21, }, + [23] = { attack_damageMore = 1.22, }, + [24] = { attack_damageMore = 1.23, }, + [25] = { attack_damageMore = 1.24, }, + [26] = { attack_damageMore = 1.25, }, + [27] = { attack_damageMore = 1.26, }, + [28] = { attack_damageMore = 1.27, }, + [29] = { attack_damageMore = 1.28, }, + [30] = { attack_damageMore = 1.29, }, + } +} +gems["Sweep"] = { + attack = true, + melee = true, + aoe = true, + base = { + skill_manaCostBase = 8, + attackSpeedMore = 0.9, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { attack_damageMore = 1, }, + [2] = { attack_damageMore = 1.01, }, + [3] = { attack_damageMore = 1.02, }, + [4] = { attack_damageMore = 1.03, }, + [5] = { attack_damageMore = 1.04, }, + [6] = { attack_damageMore = 1.05, }, + [7] = { attack_damageMore = 1.06, }, + [8] = { attack_damageMore = 1.07, }, + [9] = { attack_damageMore = 1.08, }, + [10] = { attack_damageMore = 1.09, }, + [11] = { attack_damageMore = 1.1, }, + [12] = { attack_damageMore = 1.11, }, + [13] = { attack_damageMore = 1.12, }, + [14] = { attack_damageMore = 1.13, }, + [15] = { attack_damageMore = 1.14, }, + [16] = { attack_damageMore = 1.15, }, + [17] = { attack_damageMore = 1.16, }, + [18] = { attack_damageMore = 1.17, }, + [19] = { attack_damageMore = 1.18, }, + [20] = { attack_damageMore = 1.19, }, + [21] = { attack_damageMore = 1.2, }, + [22] = { attack_damageMore = 1.21, }, + [23] = { attack_damageMore = 1.22, }, + [24] = { attack_damageMore = 1.23, }, + [25] = { attack_damageMore = 1.24, }, + [26] = { attack_damageMore = 1.25, }, + [27] = { attack_damageMore = 1.26, }, + [28] = { attack_damageMore = 1.27, }, + [29] = { attack_damageMore = 1.28, }, + [30] = { attack_damageMore = 1.29, }, + } +} +gems["Vengeance"] = { + unsupported = true, +} +gems["Vigilant Strike"] = { + attack = true, + melee = true, + base = { + skill_manaCostBase = 6, + skill_noEvade = true, + cond_Fortify = true, + }, + quality = { + fortifyDurInc = 1, + }, + levels = { + [1] = { attack_damageMore = 1.65, }, + [2] = { attack_damageMore = 1.67, }, + [3] = { attack_damageMore = 1.69, }, + [4] = { attack_damageMore = 1.71, }, + [5] = { attack_damageMore = 1.73, }, + [6] = { attack_damageMore = 1.75, }, + [7] = { attack_damageMore = 1.77, }, + [8] = { attack_damageMore = 1.79, }, + [9] = { attack_damageMore = 1.81, }, + [10] = { attack_damageMore = 1.83, }, + [11] = { attack_damageMore = 1.85, }, + [12] = { attack_damageMore = 1.87, }, + [13] = { attack_damageMore = 1.89, }, + [14] = { attack_damageMore = 1.91, }, + [15] = { attack_damageMore = 1.93, }, + [16] = { attack_damageMore = 1.95, }, + [17] = { attack_damageMore = 1.97, }, + [18] = { attack_damageMore = 1.99, }, + [19] = { attack_damageMore = 2.01, }, + [20] = { attack_damageMore = 2.03, }, + [21] = { attack_damageMore = 2.05, }, + [22] = { attack_damageMore = 2.07, }, + [23] = { attack_damageMore = 2.09, }, + [24] = { attack_damageMore = 2.11, }, + [25] = { attack_damageMore = 2.13, }, + [26] = { attack_damageMore = 2.15, }, + [27] = { attack_damageMore = 2.17, }, + [28] = { attack_damageMore = 2.19, }, + [29] = { attack_damageMore = 2.21, }, + [30] = { attack_damageMore = 2.23, }, + } +} +gems["Vitality"] = { + aura = true, + spell = true, + aoe = true, + base = { + skill_manaReservedPercent = 35, + }, + quality = { + auraRadiusInc = 1, + }, + levels = { + [1] = { lifeRegenPercent = 0.7, auraRadiusInc = 0, }, + [2] = { lifeRegenPercent = 0.75, auraRadiusInc = 3, }, + [3] = { lifeRegenPercent = 0.8, auraRadiusInc = 6, }, + [4] = { lifeRegenPercent = 0.85, auraRadiusInc = 9, }, + [5] = { lifeRegenPercent = 0.9, auraRadiusInc = 12, }, + [6] = { lifeRegenPercent = 0.95, auraRadiusInc = 15, }, + [7] = { lifeRegenPercent = 1, auraRadiusInc = 18, }, + [8] = { lifeRegenPercent = 1.05, auraRadiusInc = 21, }, + [9] = { lifeRegenPercent = 1.1, auraRadiusInc = 23, }, + [10] = { lifeRegenPercent = 1.15, auraRadiusInc = 25, }, + [11] = { lifeRegenPercent = 1.2, auraRadiusInc = 27, }, + [12] = { lifeRegenPercent = 1.25, auraRadiusInc = 29, }, + [13] = { lifeRegenPercent = 1.3, auraRadiusInc = 31, }, + [14] = { lifeRegenPercent = 1.35, auraRadiusInc = 33, }, + [15] = { lifeRegenPercent = 1.4, auraRadiusInc = 35, }, + [16] = { lifeRegenPercent = 1.45, auraRadiusInc = 36, }, + [17] = { lifeRegenPercent = 1.5, auraRadiusInc = 37, }, + [18] = { lifeRegenPercent = 1.55, auraRadiusInc = 38, }, + [19] = { lifeRegenPercent = 1.6, auraRadiusInc = 39, }, + [20] = { lifeRegenPercent = 1.65, auraRadiusInc = 40, }, + [21] = { lifeRegenPercent = 1.7, auraRadiusInc = 41, }, + [22] = { lifeRegenPercent = 1.75, auraRadiusInc = 42, }, + [23] = { lifeRegenPercent = 1.8, auraRadiusInc = 43, }, + [24] = { lifeRegenPercent = 1.85, auraRadiusInc = 44, }, + [25] = { lifeRegenPercent = 1.9, auraRadiusInc = 45, }, + [26] = { lifeRegenPercent = 1.95, auraRadiusInc = 46, }, + [27] = { lifeRegenPercent = 2, auraRadiusInc = 47, }, + [28] = { lifeRegenPercent = 2.05, auraRadiusInc = 48, }, + [29] = { lifeRegenPercent = 2.1, auraRadiusInc = 49, }, + [30] = { lifeRegenPercent = 2.15, auraRadiusInc = 50, }, + } +} +gems["Warlord's Mark"] = { + unsupported = true, +} + diff --git a/Gems/sup_dex.lua b/Gems/sup_dex.lua new file mode 100644 index 00000000..86ad0655 --- /dev/null +++ b/Gems/sup_dex.lua @@ -0,0 +1,1169 @@ +local gems = ... + +gems["Added Cold Damage"] = { + support = true, + cold = true, + base = { + manaCostMore = 1.3, + }, + quality = { + coldInc = 0.5, + }, + levels = { + [1] = { coldMin = 4, coldMax = 6, }, + [2] = { coldMin = 5, coldMax = 7, }, + [3] = { coldMin = 6, coldMax = 9, }, + [4] = { coldMin = 8, coldMax = 11, }, + [5] = { coldMin = 10, coldMax = 15, }, + [6] = { coldMin = 13, coldMax = 19, }, + [7] = { coldMin = 16, coldMax = 24, }, + [8] = { coldMin = 20, coldMax = 31, }, + [9] = { coldMin = 25, coldMax = 38, }, + [10] = { coldMin = 30, coldMax = 45, }, + [11] = { coldMin = 35, coldMax = 52, }, + [12] = { coldMin = 40, coldMax = 61, }, + [13] = { coldMin = 47, coldMax = 70, }, + [14] = { coldMin = 54, coldMax = 81, }, + [15] = { coldMin = 63, coldMax = 94, }, + [16] = { coldMin = 72, coldMax = 108, }, + [17] = { coldMin = 83, coldMax = 125, }, + [18] = { coldMin = 95, coldMax = 143, }, + [19] = { coldMin = 109, coldMax = 164, }, + [20] = { coldMin = 125, coldMax = 188, }, + [21] = { coldMin = 137, coldMax = 205, }, + [22] = { coldMin = 149, coldMax = 224, }, + [23] = { coldMin = 163, coldMax = 245, }, + [24] = { coldMin = 178, coldMax = 267, }, + [25] = { coldMin = 194, coldMax = 291, }, + [26] = { coldMin = 212, coldMax = 318, }, + [27] = { coldMin = 231, coldMax = 346, }, + [28] = { coldMin = 251, coldMax = 377, }, + [29] = { coldMin = 274, coldMax = 411, }, + [30] = { coldMin = 298, coldMax = 447, }, + } +} +gems["Additional Accuracy"] = { + support = true, + attack = true, + base = { + }, + quality = { + accuracyInc = 1, + }, + levels = { + [1] = { accuracyBase = 74, }, + [2] = { accuracyBase = 100, }, + [3] = { accuracyBase = 127, }, + [4] = { accuracyBase = 157, }, + [5] = { accuracyBase = 190, }, + [6] = { accuracyBase = 230, }, + [7] = { accuracyBase = 290, }, + [8] = { accuracyBase = 350, }, + [9] = { accuracyBase = 400, }, + [10] = { accuracyBase = 453, }, + [11] = { accuracyBase = 528, }, + [12] = { accuracyBase = 586, }, + [13] = { accuracyBase = 645, }, + [14] = { accuracyBase = 707, }, + [15] = { accuracyBase = 772, }, + [16] = { accuracyBase = 840, }, + [17] = { accuracyBase = 887, }, + [18] = { accuracyBase = 934, }, + [19] = { accuracyBase = 983, }, + [20] = { accuracyBase = 1034, }, + [21] = { accuracyBase = 1085, }, + [22] = { accuracyBase = 1138, }, + [23] = { accuracyBase = 1191, }, + [24] = { accuracyBase = 1246, }, + [25] = { accuracyBase = 1301, }, + [26] = { accuracyBase = 1358, }, + [27] = { accuracyBase = 1415, }, + [28] = { accuracyBase = 1474, }, + [29] = { accuracyBase = 1533, }, + [30] = { accuracyBase = 1594, }, + } +} +gems["Blind"] = { + support = true, + base = { + }, + quality = { + }, + levels = { + [1] = { }, + [2] = { }, + [3] = { }, + [4] = { }, + [5] = { }, + [6] = { }, + [7] = { }, + [8] = { }, + [9] = { }, + [10] = { }, + [11] = { }, + [12] = { }, + [13] = { }, + [14] = { }, + [15] = { }, + [16] = { }, + [17] = { }, + [18] = { }, + [19] = { }, + [20] = { }, + [21] = { }, + [22] = { }, + [23] = { }, + [24] = { }, + [25] = { }, + [26] = { }, + [27] = { }, + [28] = { }, + [29] = { }, + [30] = { }, + } +} +gems["Block Chance Reduction"] = { + unsupported = true, +} +gems["Cast on Critical Strike"] = { + unsupported = true, +} +gems["Cast on Death"] = { + unsupported = true, +} +gems["Chain"] = { + support = true, + projectile = true, + base = { + manaCostMore = 1.5, + }, + quality = { + projectileSpeedInc = 1, + }, + levels = { + [1] = { damageMore = 0.5, }, + [2] = { damageMore = 0.51, }, + [3] = { damageMore = 0.52, }, + [4] = { damageMore = 0.53, }, + [5] = { damageMore = 0.54, }, + [6] = { damageMore = 0.55, }, + [7] = { damageMore = 0.56, }, + [8] = { damageMore = 0.57, }, + [9] = { damageMore = 0.58, }, + [10] = { damageMore = 0.59, }, + [11] = { damageMore = 0.6, }, + [12] = { damageMore = 0.61, }, + [13] = { damageMore = 0.62, }, + [14] = { damageMore = 0.63, }, + [15] = { damageMore = 0.64, }, + [16] = { damageMore = 0.65, }, + [17] = { damageMore = 0.66, }, + [18] = { damageMore = 0.67, }, + [19] = { damageMore = 0.68, }, + [20] = { damageMore = 0.69, }, + [21] = { damageMore = 0.7, }, + [22] = { damageMore = 0.71, }, + [23] = { damageMore = 0.72, }, + [24] = { damageMore = 0.73, }, + [25] = { damageMore = 0.74, }, + [26] = { damageMore = 0.75, }, + [27] = { damageMore = 0.76, }, + [28] = { damageMore = 0.77, }, + [29] = { damageMore = 0.78, }, + [30] = { damageMore = 0.79, }, + } +} +gems["Chance to Flee"] = { + support = true, + base = { + }, + quality = { + }, + levels = { + [1] = { }, + [2] = { }, + [3] = { }, + [4] = { }, + [5] = { }, + [6] = { }, + [7] = { }, + [8] = { }, + [9] = { }, + [10] = { }, + [11] = { }, + [12] = { }, + [13] = { }, + [14] = { }, + [15] = { }, + [16] = { }, + [17] = { }, + [18] = { }, + [19] = { }, + [20] = { }, + [21] = { }, + [22] = { }, + [23] = { }, + [24] = { }, + [25] = { }, + [26] = { }, + [27] = { }, + [28] = { }, + [29] = { }, + [30] = { }, + } +} +gems["Cluster Traps"] = { + support = true, + trap = true, + base = { + manaCostMore = 1.5, + }, + quality = { + trap_damageInc = 0.5, + }, + levels = { + [1] = { trap_damageMore = 0.45, }, + [2] = { trap_damageMore = 0.46, }, + [3] = { trap_damageMore = 0.47, }, + [4] = { trap_damageMore = 0.48, }, + [5] = { trap_damageMore = 0.49, }, + [6] = { trap_damageMore = 0.5, }, + [7] = { trap_damageMore = 0.51, }, + [8] = { trap_damageMore = 0.52, }, + [9] = { trap_damageMore = 0.53, }, + [10] = { trap_damageMore = 0.54, }, + [11] = { trap_damageMore = 0.55, }, + [12] = { trap_damageMore = 0.56, }, + [13] = { trap_damageMore = 0.57, }, + [14] = { trap_damageMore = 0.58, }, + [15] = { trap_damageMore = 0.59, }, + [16] = { trap_damageMore = 0.6, }, + [17] = { trap_damageMore = 0.61, }, + [18] = { trap_damageMore = 0.62, }, + [19] = { trap_damageMore = 0.63, }, + [20] = { trap_damageMore = 0.64, }, + [21] = { trap_damageMore = 0.65, }, + [22] = { trap_damageMore = 0.66, }, + [23] = { trap_damageMore = 0.67, }, + [24] = { trap_damageMore = 0.68, }, + [25] = { trap_damageMore = 0.69, }, + [26] = { trap_damageMore = 0.7, }, + [27] = { trap_damageMore = 0.71, }, + [28] = { trap_damageMore = 0.72, }, + [29] = { trap_damageMore = 0.73, }, + [30] = { trap_damageMore = 0.74, }, + } +} +gems["Cold Penetration"] = { + support = true, + cold = true, + base = { + manaCostMore = 1.4, + }, + quality = { + coldInc = 0.5, + }, + levels = { + [1] = { coldPen = 18, }, + [2] = { coldPen = 19, }, + [3] = { coldPen = 20, }, + [4] = { coldPen = 21, }, + [5] = { coldPen = 22, }, + [6] = { coldPen = 23, }, + [7] = { coldPen = 24, }, + [8] = { coldPen = 25, }, + [9] = { coldPen = 26, }, + [10] = { coldPen = 27, }, + [11] = { coldPen = 28, }, + [12] = { coldPen = 29, }, + [13] = { coldPen = 30, }, + [14] = { coldPen = 31, }, + [15] = { coldPen = 32, }, + [16] = { coldPen = 33, }, + [17] = { coldPen = 34, }, + [18] = { coldPen = 35, }, + [19] = { coldPen = 36, }, + [20] = { coldPen = 37, }, + [21] = { coldPen = 38, }, + [22] = { coldPen = 39, }, + [23] = { coldPen = 40, }, + [24] = { coldPen = 41, }, + [25] = { coldPen = 42, }, + [26] = { coldPen = 43, }, + [27] = { coldPen = 44, }, + [28] = { coldPen = 45, }, + [29] = { coldPen = 46, }, + [30] = { coldPen = 47, }, + } +} +gems["Culling Strike"] = { + support = true, + base = { + manaCostMore = 1.1, + }, + quality = { + speedInc = 0.5, + }, + levels = { + [1] = { damageInc = 0, }, + [2] = { damageInc = 2, }, + [3] = { damageInc = 4, }, + [4] = { damageInc = 6, }, + [5] = { damageInc = 8, }, + [6] = { damageInc = 10, }, + [7] = { damageInc = 12, }, + [8] = { damageInc = 14, }, + [9] = { damageInc = 16, }, + [10] = { damageInc = 18, }, + [11] = { damageInc = 20, }, + [12] = { damageInc = 22, }, + [13] = { damageInc = 24, }, + [14] = { damageInc = 26, }, + [15] = { damageInc = 28, }, + [16] = { damageInc = 30, }, + [17] = { damageInc = 32, }, + [18] = { damageInc = 34, }, + [19] = { damageInc = 36, }, + [20] = { damageInc = 38, }, + [21] = { damageInc = 40, }, + [22] = { damageInc = 42, }, + [23] = { damageInc = 44, }, + [24] = { damageInc = 46, }, + [25] = { damageInc = 48, }, + [26] = { damageInc = 50, }, + [27] = { damageInc = 52, }, + [28] = { damageInc = 54, }, + [29] = { damageInc = 56, }, + [30] = { damageInc = 58, }, + } +} +gems["Enhance"] = { + support = true, + base = { + manaCostMore = 1.15, + }, + quality = { + }, + levels = { + [1] = { }, + [2] = { }, + [3] = { }, + [4] = { }, + [5] = { }, + [6] = { }, + [7] = { }, + [8] = { }, + [9] = { }, + [10] = { }, + } +} +gems["Faster Attacks"] = { + support = true, + attack = true, + base = { + manaCostMore = 1.15, + }, + quality = { + attackSpeedInc = 0.5, + }, + levels = { + [1] = { attackSpeedInc = 25, }, + [2] = { attackSpeedInc = 26, }, + [3] = { attackSpeedInc = 27, }, + [4] = { attackSpeedInc = 28, }, + [5] = { attackSpeedInc = 29, }, + [6] = { attackSpeedInc = 30, }, + [7] = { attackSpeedInc = 31, }, + [8] = { attackSpeedInc = 32, }, + [9] = { attackSpeedInc = 33, }, + [10] = { attackSpeedInc = 34, }, + [11] = { attackSpeedInc = 35, }, + [12] = { attackSpeedInc = 36, }, + [13] = { attackSpeedInc = 37, }, + [14] = { attackSpeedInc = 38, }, + [15] = { attackSpeedInc = 39, }, + [16] = { attackSpeedInc = 40, }, + [17] = { attackSpeedInc = 41, }, + [18] = { attackSpeedInc = 42, }, + [19] = { attackSpeedInc = 43, }, + [20] = { attackSpeedInc = 44, }, + [21] = { attackSpeedInc = 45, }, + [22] = { attackSpeedInc = 46, }, + [23] = { attackSpeedInc = 47, }, + [24] = { attackSpeedInc = 48, }, + [25] = { attackSpeedInc = 49, }, + [26] = { attackSpeedInc = 50, }, + [27] = { attackSpeedInc = 51, }, + [28] = { attackSpeedInc = 52, }, + [29] = { attackSpeedInc = 53, }, + [30] = { attackSpeedInc = 54, }, + } +} +gems["Faster Projectiles"] = { + support = true, + projectile = true, + base = { + manaCostMore = 1.1, + }, + quality = { + speedInc = 0.5, + }, + levels = { + [1] = { projectileSpeedInc = 50, projectile_damageInc = 20, }, + [2] = { projectileSpeedInc = 51, projectile_damageInc = 20, }, + [3] = { projectileSpeedInc = 52, projectile_damageInc = 21, }, + [4] = { projectileSpeedInc = 53, projectile_damageInc = 21, }, + [5] = { projectileSpeedInc = 54, projectile_damageInc = 22, }, + [6] = { projectileSpeedInc = 55, projectile_damageInc = 22, }, + [7] = { projectileSpeedInc = 56, projectile_damageInc = 23, }, + [8] = { projectileSpeedInc = 57, projectile_damageInc = 23, }, + [9] = { projectileSpeedInc = 58, projectile_damageInc = 24, }, + [10] = { projectileSpeedInc = 59, projectile_damageInc = 24, }, + [11] = { projectileSpeedInc = 60, projectile_damageInc = 25, }, + [12] = { projectileSpeedInc = 61, projectile_damageInc = 25, }, + [13] = { projectileSpeedInc = 62, projectile_damageInc = 26, }, + [14] = { projectileSpeedInc = 63, projectile_damageInc = 26, }, + [15] = { projectileSpeedInc = 64, projectile_damageInc = 27, }, + [16] = { projectileSpeedInc = 65, projectile_damageInc = 27, }, + [17] = { projectileSpeedInc = 66, projectile_damageInc = 28, }, + [18] = { projectileSpeedInc = 67, projectile_damageInc = 28, }, + [19] = { projectileSpeedInc = 68, projectile_damageInc = 29, }, + [20] = { projectileSpeedInc = 69, projectile_damageInc = 29, }, + [21] = { projectileSpeedInc = 70, projectile_damageInc = 30, }, + [22] = { projectileSpeedInc = 71, projectile_damageInc = 30, }, + [23] = { projectileSpeedInc = 72, projectile_damageInc = 31, }, + [24] = { projectileSpeedInc = 73, projectile_damageInc = 31, }, + [25] = { projectileSpeedInc = 74, projectile_damageInc = 32, }, + [26] = { projectileSpeedInc = 75, projectile_damageInc = 32, }, + [27] = { projectileSpeedInc = 76, projectile_damageInc = 33, }, + [28] = { projectileSpeedInc = 77, projectile_damageInc = 33, }, + [29] = { projectileSpeedInc = 78, projectile_damageInc = 34, }, + [30] = { projectileSpeedInc = 79, projectile_damageInc = 34, }, + } +} +gems["Fork"] = { + support = true, + projectile = true, + base = { + manaCostMore = 1.3, + }, + quality = { + projectile_damageInc = 0.5, + }, + levels = { + [1] = { projectile_damageMore = 0.7, }, + [2] = { projectile_damageMore = 0.71, }, + [3] = { projectile_damageMore = 0.72, }, + [4] = { projectile_damageMore = 0.73, }, + [5] = { projectile_damageMore = 0.74, }, + [6] = { projectile_damageMore = 0.75, }, + [7] = { projectile_damageMore = 0.76, }, + [8] = { projectile_damageMore = 0.77, }, + [9] = { projectile_damageMore = 0.78, }, + [10] = { projectile_damageMore = 0.79, }, + [11] = { projectile_damageMore = 0.8, }, + [12] = { projectile_damageMore = 0.81, }, + [13] = { projectile_damageMore = 0.82, }, + [14] = { projectile_damageMore = 0.83, }, + [15] = { projectile_damageMore = 0.84, }, + [16] = { projectile_damageMore = 0.85, }, + [17] = { projectile_damageMore = 0.86, }, + [18] = { projectile_damageMore = 0.87, }, + [19] = { projectile_damageMore = 0.88, }, + [20] = { projectile_damageMore = 0.89, }, + [21] = { projectile_damageMore = 0.9, }, + [22] = { projectile_damageMore = 0.91, }, + [23] = { projectile_damageMore = 0.92, }, + [24] = { projectile_damageMore = 0.93, }, + [25] = { projectile_damageMore = 0.94, }, + [26] = { projectile_damageMore = 0.95, }, + [27] = { projectile_damageMore = 0.96, }, + [28] = { projectile_damageMore = 0.97, }, + [29] = { projectile_damageMore = 0.98, }, + [30] = { projectile_damageMore = 0.99, }, + } +} +gems["Greater Multiple Projectiles"] = { + support = true, + projectile = true, + base = { + manaCostMore = 1.65, + }, + quality = { + speedInc = 0.5, + }, + levels = { + [1] = { projectile_damageMore = 0.65, }, + [2] = { projectile_damageMore = 0.65, }, + [3] = { projectile_damageMore = 0.66, }, + [4] = { projectile_damageMore = 0.66, }, + [5] = { projectile_damageMore = 0.67, }, + [6] = { projectile_damageMore = 0.67, }, + [7] = { projectile_damageMore = 0.68, }, + [8] = { projectile_damageMore = 0.68, }, + [9] = { projectile_damageMore = 0.69, }, + [10] = { projectile_damageMore = 0.69, }, + [11] = { projectile_damageMore = 0.7, }, + [12] = { projectile_damageMore = 0.7, }, + [13] = { projectile_damageMore = 0.71, }, + [14] = { projectile_damageMore = 0.71, }, + [15] = { projectile_damageMore = 0.72, }, + [16] = { projectile_damageMore = 0.72, }, + [17] = { projectile_damageMore = 0.73, }, + [18] = { projectile_damageMore = 0.73, }, + [19] = { projectile_damageMore = 0.74, }, + [20] = { projectile_damageMore = 0.74, }, + [21] = { projectile_damageMore = 0.75, }, + [22] = { projectile_damageMore = 0.75, }, + [23] = { projectile_damageMore = 0.76, }, + [24] = { projectile_damageMore = 0.76, }, + [25] = { projectile_damageMore = 0.77, }, + [26] = { projectile_damageMore = 0.77, }, + [27] = { projectile_damageMore = 0.78, }, + [28] = { projectile_damageMore = 0.78, }, + [29] = { projectile_damageMore = 0.79, }, + [30] = { projectile_damageMore = 0.79, }, + } +} +gems["Hypothermia"] = { + support = true, + cold = true, + base = { + manaCostMore = 1.2, + condMod_EnemyChilled_freezeChance = 10, + }, + quality = { + chill_durationInc = 1.5, + }, + levels = { + [1] = { condMod_EnemyChilled_damageMore = 1.2, }, + [2] = { condMod_EnemyChilled_damageMore = 1.21, }, + [3] = { condMod_EnemyChilled_damageMore = 1.22, }, + [4] = { condMod_EnemyChilled_damageMore = 1.23, }, + [5] = { condMod_EnemyChilled_damageMore = 1.24, }, + [6] = { condMod_EnemyChilled_damageMore = 1.25, }, + [7] = { condMod_EnemyChilled_damageMore = 1.26, }, + [8] = { condMod_EnemyChilled_damageMore = 1.27, }, + [9] = { condMod_EnemyChilled_damageMore = 1.28, }, + [10] = { condMod_EnemyChilled_damageMore = 1.29, }, + [11] = { condMod_EnemyChilled_damageMore = 1.3, }, + [12] = { condMod_EnemyChilled_damageMore = 1.31, }, + [13] = { condMod_EnemyChilled_damageMore = 1.32, }, + [14] = { condMod_EnemyChilled_damageMore = 1.33, }, + [15] = { condMod_EnemyChilled_damageMore = 1.34, }, + [16] = { condMod_EnemyChilled_damageMore = 1.35, }, + [17] = { condMod_EnemyChilled_damageMore = 1.36, }, + [18] = { condMod_EnemyChilled_damageMore = 1.37, }, + [19] = { condMod_EnemyChilled_damageMore = 1.38, }, + [20] = { condMod_EnemyChilled_damageMore = 1.39, }, + [21] = { condMod_EnemyChilled_damageMore = 1.4, }, + [22] = { condMod_EnemyChilled_damageMore = 1.41, }, + [23] = { condMod_EnemyChilled_damageMore = 1.42, }, + [24] = { condMod_EnemyChilled_damageMore = 1.43, }, + [25] = { condMod_EnemyChilled_damageMore = 1.44, }, + [26] = { condMod_EnemyChilled_damageMore = 1.45, }, + [27] = { condMod_EnemyChilled_damageMore = 1.46, }, + [28] = { condMod_EnemyChilled_damageMore = 1.47, }, + [29] = { condMod_EnemyChilled_damageMore = 1.48, }, + [30] = { condMod_EnemyChilled_damageMore = 1.49, }, + } +} +gems["Ice Bite"] = { + support = true, + cold = true, + base = { + manaCostMore = 1.1, + freezeChance = 15, + }, + quality = { + condMod_EnemyFreeze_damageInc = 1, + }, + levels = { + [1] = { }, + [2] = { }, + [3] = { }, + [4] = { }, + [5] = { }, + [6] = { }, + [7] = { }, + [8] = { }, + [9] = { }, + [10] = { }, + [11] = { }, + [12] = { }, + [13] = { }, + [14] = { }, + [15] = { }, + [16] = { }, + [17] = { }, + [18] = { }, + [19] = { }, + [20] = { }, + [21] = { }, + [22] = { }, + [23] = { }, + [24] = { }, + [25] = { }, + [26] = { }, + [27] = { }, + [28] = { }, + [29] = { }, + [30] = { }, + } +} +gems["Lesser Multiple Projectiles"] = { + support = true, + projectile = true, + base = { + manaCostMore = 1.4, + }, + quality = { + speedInc = 0.5, + }, + levels = { + [1] = { projectile_damageMore = 0.75, }, + [2] = { projectile_damageMore = 0.75, }, + [3] = { projectile_damageMore = 0.76, }, + [4] = { projectile_damageMore = 0.76, }, + [5] = { projectile_damageMore = 0.77, }, + [6] = { projectile_damageMore = 0.77, }, + [7] = { projectile_damageMore = 0.78, }, + [8] = { projectile_damageMore = 0.78, }, + [9] = { projectile_damageMore = 0.79, }, + [10] = { projectile_damageMore = 0.79, }, + [11] = { projectile_damageMore = 0.8, }, + [12] = { projectile_damageMore = 0.8, }, + [13] = { projectile_damageMore = 0.81, }, + [14] = { projectile_damageMore = 0.81, }, + [15] = { projectile_damageMore = 0.82, }, + [16] = { projectile_damageMore = 0.82, }, + [17] = { projectile_damageMore = 0.83, }, + [18] = { projectile_damageMore = 0.83, }, + [19] = { projectile_damageMore = 0.835, }, -- EDITED + [20] = { projectile_damageMore = 0.84, }, + [21] = { projectile_damageMore = 0.85, }, + [22] = { projectile_damageMore = 0.85, }, + [23] = { projectile_damageMore = 0.86, }, + [24] = { projectile_damageMore = 0.86, }, + [25] = { projectile_damageMore = 0.87, }, + [26] = { projectile_damageMore = 0.87, }, + [27] = { projectile_damageMore = 0.88, }, + [28] = { projectile_damageMore = 0.88, }, + [29] = { projectile_damageMore = 0.89, }, + [30] = { projectile_damageMore = 0.89, }, + } +} +gems["Mana Leech"] = { + support = true, + base = { + }, + quality = { + }, + levels = { + [1] = { }, + [2] = { }, + [3] = { }, + [4] = { }, + [5] = { }, + [6] = { }, + [7] = { }, + [8] = { }, + [9] = { }, + [10] = { }, + [11] = { }, + [12] = { }, + [13] = { }, + [14] = { }, + [15] = { }, + [16] = { }, + [17] = { }, + [18] = { }, + [19] = { }, + [20] = { }, + [21] = { }, + [22] = { }, + [23] = { }, + [24] = { }, + [25] = { }, + [26] = { }, + [27] = { }, + [28] = { }, + [29] = { }, + [30] = { }, + } +} +gems["Multiple Traps"] = { + support = true, + trap = true, + base = { + manaCostMore = 1.6, + }, + quality = { + trapTriggerRadiusInc = 1, + }, + levels = { + [1] = { trap_damageMore = 0.6, }, + [2] = { trap_damageMore = 0.61, }, + [3] = { trap_damageMore = 0.62, }, + [4] = { trap_damageMore = 0.63, }, + [5] = { trap_damageMore = 0.64, }, + [6] = { trap_damageMore = 0.65, }, + [7] = { trap_damageMore = 0.66, }, + [8] = { trap_damageMore = 0.67, }, + [9] = { trap_damageMore = 0.68, }, + [10] = { trap_damageMore = 0.69, }, + [11] = { trap_damageMore = 0.7, }, + [12] = { trap_damageMore = 0.71, }, + [13] = { trap_damageMore = 0.72, }, + [14] = { trap_damageMore = 0.73, }, + [15] = { trap_damageMore = 0.74, }, + [16] = { trap_damageMore = 0.75, }, + [17] = { trap_damageMore = 0.76, }, + [18] = { trap_damageMore = 0.77, }, + [19] = { trap_damageMore = 0.78, }, + [20] = { trap_damageMore = 0.79, }, + [21] = { trap_damageMore = 0.8, }, + [22] = { trap_damageMore = 0.81, }, + [23] = { trap_damageMore = 0.82, }, + [24] = { trap_damageMore = 0.83, }, + [25] = { trap_damageMore = 0.84, }, + [26] = { trap_damageMore = 0.85, }, + [27] = { trap_damageMore = 0.86, }, + [28] = { trap_damageMore = 0.87, }, + [29] = { trap_damageMore = 0.88, }, + [30] = { trap_damageMore = 0.89, }, + } +} +gems["Physical Projectile Attack Damage"] = { + support = true, + attack = true, + projectile = true, + base = { + manaCostMore = 1.2, + projectile_attackSpeedMore = 0.9, + }, + quality = { + physicalInc = 0.5, + }, + levels = { + [1] = { projectile_physicalMore = 1.3, }, + [2] = { projectile_physicalMore = 1.31, }, + [3] = { projectile_physicalMore = 1.32, }, + [4] = { projectile_physicalMore = 1.33, }, + [5] = { projectile_physicalMore = 1.34, }, + [6] = { projectile_physicalMore = 1.35, }, + [7] = { projectile_physicalMore = 1.36, }, + [8] = { projectile_physicalMore = 1.37, }, + [9] = { projectile_physicalMore = 1.38, }, + [10] = { projectile_physicalMore = 1.39, }, + [11] = { projectile_physicalMore = 1.4, }, + [12] = { projectile_physicalMore = 1.41, }, + [13] = { projectile_physicalMore = 1.42, }, + [14] = { projectile_physicalMore = 1.43, }, + [15] = { projectile_physicalMore = 1.44, }, + [16] = { projectile_physicalMore = 1.45, }, + [17] = { projectile_physicalMore = 1.46, }, + [18] = { projectile_physicalMore = 1.47, }, + [19] = { projectile_physicalMore = 1.48, }, + [20] = { projectile_physicalMore = 1.49, }, + [21] = { projectile_physicalMore = 1.5, }, + [22] = { projectile_physicalMore = 1.51, }, + [23] = { projectile_physicalMore = 1.52, }, + [24] = { projectile_physicalMore = 1.53, }, + [25] = { projectile_physicalMore = 1.54, }, + [26] = { projectile_physicalMore = 1.55, }, + [27] = { projectile_physicalMore = 1.56, }, + [28] = { projectile_physicalMore = 1.57, }, + [29] = { projectile_physicalMore = 1.58, }, + [30] = { projectile_physicalMore = 1.59, }, + } +} +gems["Pierce"] = { + support = true, + projectile = true, + base = { + manaCostMore = 1.1, + pierceChance = 50, + }, + quality = { + projectile_damageInc = 0.5, + }, + levels = { + [1] = { projectile_damageMore = 1.1, }, + [2] = { projectile_damageMore = 1.11, }, + [3] = { projectile_damageMore = 1.12, }, + [4] = { projectile_damageMore = 1.13, }, + [5] = { projectile_damageMore = 1.14, }, + [6] = { projectile_damageMore = 1.15, }, + [7] = { projectile_damageMore = 1.16, }, + [8] = { projectile_damageMore = 1.17, }, + [9] = { projectile_damageMore = 1.18, }, + [10] = { projectile_damageMore = 1.19, }, + [11] = { projectile_damageMore = 1.2, }, + [12] = { projectile_damageMore = 1.21, }, + [13] = { projectile_damageMore = 1.22, }, + [14] = { projectile_damageMore = 1.23, }, + [15] = { projectile_damageMore = 1.24, }, + [16] = { projectile_damageMore = 1.25, }, + [17] = { projectile_damageMore = 1.26, }, + [18] = { projectile_damageMore = 1.27, }, + [19] = { projectile_damageMore = 1.28, }, + [20] = { projectile_damageMore = 1.29, }, + [21] = { projectile_damageMore = 1.3, }, + [22] = { projectile_damageMore = 1.31, }, + [23] = { projectile_damageMore = 1.32, }, + [24] = { projectile_damageMore = 1.33, }, + [25] = { projectile_damageMore = 1.34, }, + [26] = { projectile_damageMore = 1.35, }, + [27] = { projectile_damageMore = 1.36, }, + [28] = { projectile_damageMore = 1.37, }, + [29] = { projectile_damageMore = 1.38, }, + [30] = { projectile_damageMore = 1.39, }, + } +} +gems["Point Blank"] = { + support = true, + attack = true, + projectile = true, + base = { + manaCostMore = 1.2, + }, + quality = { + projectile_damageInc = 0.5, + }, + levels = { + [1] = { projectile_damageInc = 0, }, + [2] = { projectile_damageInc = 2, }, + [3] = { projectile_damageInc = 4, }, + [4] = { projectile_damageInc = 6, }, + [5] = { projectile_damageInc = 8, }, + [6] = { projectile_damageInc = 10, }, + [7] = { projectile_damageInc = 12, }, + [8] = { projectile_damageInc = 14, }, + [9] = { projectile_damageInc = 16, }, + [10] = { projectile_damageInc = 18, }, + [11] = { projectile_damageInc = 20, }, + [12] = { projectile_damageInc = 22, }, + [13] = { projectile_damageInc = 24, }, + [14] = { projectile_damageInc = 26, }, + [15] = { projectile_damageInc = 28, }, + [16] = { projectile_damageInc = 30, }, + [17] = { projectile_damageInc = 32, }, + [18] = { projectile_damageInc = 34, }, + [19] = { projectile_damageInc = 36, }, + [20] = { projectile_damageInc = 38, }, + [21] = { projectile_damageInc = 40, }, + [22] = { projectile_damageInc = 42, }, + [23] = { projectile_damageInc = 44, }, + [24] = { projectile_damageInc = 46, }, + [25] = { projectile_damageInc = 48, }, + [26] = { projectile_damageInc = 50, }, + [27] = { projectile_damageInc = 52, }, + [28] = { projectile_damageInc = 54, }, + [29] = { projectile_damageInc = 56, }, + [30] = { projectile_damageInc = 58, }, + } +} +gems["Poison"] = { + support = true, + chaos = true, + base = { + manaCostMore = 1.35, + poisonChance = 100, + }, + quality = { + poison_durationInc = 0.5 + }, + levels = { + [1] = { poison_damageInc = 0, }, + [2] = { poison_damageInc = 2, }, + [3] = { poison_damageInc = 4, }, + [4] = { poison_damageInc = 6, }, + [5] = { poison_damageInc = 8, }, + [6] = { poison_damageInc = 10, }, + [7] = { poison_damageInc = 12, }, + [8] = { poison_damageInc = 14, }, + [9] = { poison_damageInc = 16, }, + [10] = { poison_damageInc = 18, }, + [11] = { poison_damageInc = 20, }, + [12] = { poison_damageInc = 22, }, + [13] = { poison_damageInc = 24, }, + [14] = { poison_damageInc = 26, }, + [15] = { poison_damageInc = 28, }, + [16] = { poison_damageInc = 30, }, + [17] = { poison_damageInc = 32, }, + [18] = { poison_damageInc = 34, }, + [19] = { poison_damageInc = 36, }, + [20] = { poison_damageInc = 38, }, + [21] = { poison_damageInc = 40, }, + [22] = { poison_damageInc = 42, }, + [23] = { poison_damageInc = 44, }, + [24] = { poison_damageInc = 46, }, + [25] = { poison_damageInc = 48, }, + [26] = { poison_damageInc = 50, }, + [27] = { poison_damageInc = 52, }, + [28] = { poison_damageInc = 54, }, + [29] = { poison_damageInc = 56, }, + [30] = { poison_damageInc = 58, }, + } +} +gems["Rapid Decay"] = { + support = true, + base = { + manaCostMore = 1.25, + durationInc = -15, + }, + quality = { + dot_damageInc = 0.5, + }, + levels = { + [1] = { dot_damageMore = 1.2, }, + [2] = { dot_damageMore = 1.21, }, + [3] = { dot_damageMore = 1.22, }, + [4] = { dot_damageMore = 1.23, }, + [5] = { dot_damageMore = 1.24, }, + [6] = { dot_damageMore = 1.25, }, + [7] = { dot_damageMore = 1.26, }, + [8] = { dot_damageMore = 1.27, }, + [9] = { dot_damageMore = 1.28, }, + [10] = { dot_damageMore = 1.29, }, + [11] = { dot_damageMore = 1.3, }, + [12] = { dot_damageMore = 1.31, }, + [13] = { dot_damageMore = 1.32, }, + [14] = { dot_damageMore = 1.33, }, + [15] = { dot_damageMore = 1.34, }, + [16] = { dot_damageMore = 1.35, }, + [17] = { dot_damageMore = 1.36, }, + [18] = { dot_damageMore = 1.37, }, + [19] = { dot_damageMore = 1.38, }, + [20] = { dot_damageMore = 1.39, }, + [21] = { dot_damageMore = 1.4, }, + [22] = { dot_damageMore = 1.41, }, + [23] = { dot_damageMore = 1.42, }, + [24] = { dot_damageMore = 1.43, }, + [25] = { dot_damageMore = 1.44, }, + [26] = { dot_damageMore = 1.45, }, + [27] = { dot_damageMore = 1.46, }, + [28] = { dot_damageMore = 1.47, }, + [29] = { dot_damageMore = 1.48, }, + [30] = { dot_damageMore = 1.49, }, + } +} +gems["Slower Projectiles"] = { + support = true, + projectile = true, + base = { + manaCostMore = 1.4, + }, + quality = { + projectile_damageInc = 0.5, + }, + levels = { + [1] = { projectileSpeedMore = 0.7, projectile_damageMore = 1.2, }, + [2] = { projectileSpeedMore = 0.69, projectile_damageMore = 1.2, }, + [3] = { projectileSpeedMore = 0.68, projectile_damageMore = 1.21, }, + [4] = { projectileSpeedMore = 0.67, projectile_damageMore = 1.21, }, + [5] = { projectileSpeedMore = 0.66, projectile_damageMore = 1.22, }, + [6] = { projectileSpeedMore = 0.65, projectile_damageMore = 1.22, }, + [7] = { projectileSpeedMore = 0.64, projectile_damageMore = 1.23, }, + [8] = { projectileSpeedMore = 0.63, projectile_damageMore = 1.23, }, + [9] = { projectileSpeedMore = 0.62, projectile_damageMore = 1.24, }, + [10] = { projectileSpeedMore = 0.61, projectile_damageMore = 1.24, }, + [11] = { projectileSpeedMore = 0.6, projectile_damageMore = 1.25, }, + [12] = { projectileSpeedMore = 0.59, projectile_damageMore = 1.25, }, + [13] = { projectileSpeedMore = 0.58, projectile_damageMore = 1.26, }, + [14] = { projectileSpeedMore = 0.57, projectile_damageMore = 1.26, }, + [15] = { projectileSpeedMore = 0.56, projectile_damageMore = 1.27, }, + [16] = { projectileSpeedMore = 0.55, projectile_damageMore = 1.27, }, + [17] = { projectileSpeedMore = 0.54, projectile_damageMore = 1.28, }, + [18] = { projectileSpeedMore = 0.53, projectile_damageMore = 1.28, }, + [19] = { projectileSpeedMore = 0.52, projectile_damageMore = 1.29, }, + [20] = { projectileSpeedMore = 0.51, projectile_damageMore = 1.29, }, + [21] = { projectileSpeedMore = 0.5, projectile_damageMore = 1.3, }, + [22] = { projectileSpeedMore = 0.49, projectile_damageMore = 1.3, }, + [23] = { projectileSpeedMore = 0.48, projectile_damageMore = 1.31, }, + [24] = { projectileSpeedMore = 0.47, projectile_damageMore = 1.31, }, + [25] = { projectileSpeedMore = 0.46, projectile_damageMore = 1.32, }, + [26] = { projectileSpeedMore = 0.45, projectile_damageMore = 1.32, }, + [27] = { projectileSpeedMore = 0.44, projectile_damageMore = 1.33, }, + [28] = { projectileSpeedMore = 0.43, projectile_damageMore = 1.33, }, + [29] = { projectileSpeedMore = 0.42, projectile_damageMore = 1.34, }, + [30] = { projectileSpeedMore = 0.41, projectile_damageMore = 1.34, }, + } +} +gems["Trap"] = { + support = true, + trap = true, + addFlags = { + trap = true, + showAverage = true, + }, + base = { + manaCostMore = 1.4, + }, + quality = { + trapThrowingSpeedInc = 0.5, + }, + levels = { + [1] = { trap_damageMore = 1.2, }, + [2] = { trap_damageMore = 1.21, }, + [3] = { trap_damageMore = 1.22, }, + [4] = { trap_damageMore = 1.23, }, + [5] = { trap_damageMore = 1.24, }, + [6] = { trap_damageMore = 1.25, }, + [7] = { trap_damageMore = 1.26, }, + [8] = { trap_damageMore = 1.27, }, + [9] = { trap_damageMore = 1.28, }, + [10] = { trap_damageMore = 1.29, }, + [11] = { trap_damageMore = 1.3, }, + [12] = { trap_damageMore = 1.31, }, + [13] = { trap_damageMore = 1.32, }, + [14] = { trap_damageMore = 1.33, }, + [15] = { trap_damageMore = 1.34, }, + [16] = { trap_damageMore = 1.35, }, + [17] = { trap_damageMore = 1.36, }, + [18] = { trap_damageMore = 1.37, }, + [19] = { trap_damageMore = 1.38, }, + [20] = { trap_damageMore = 1.39, }, + [21] = { trap_damageMore = 1.4, }, + [22] = { trap_damageMore = 1.41, }, + [23] = { trap_damageMore = 1.42, }, + [24] = { trap_damageMore = 1.43, }, + [25] = { trap_damageMore = 1.44, }, + [26] = { trap_damageMore = 1.45, }, + [27] = { trap_damageMore = 1.46, }, + [28] = { trap_damageMore = 1.47, }, + [29] = { trap_damageMore = 1.48, }, + [30] = { trap_damageMore = 1.49, }, + } +} +gems["Trap Cooldown"] = { + support = true, + trap = true, + base = { + manaCostMore = 1.1, + }, + quality = { + trap_damageInc = 0.5, + }, + levels = { + [1] = { trapCooldownRecoveryInc = 30, }, + [2] = { trapCooldownRecoveryInc = 31, }, + [3] = { trapCooldownRecoveryInc = 32, }, + [4] = { trapCooldownRecoveryInc = 33, }, + [5] = { trapCooldownRecoveryInc = 34, }, + [6] = { trapCooldownRecoveryInc = 35, }, + [7] = { trapCooldownRecoveryInc = 36, }, + [8] = { trapCooldownRecoveryInc = 37, }, + [9] = { trapCooldownRecoveryInc = 38, }, + [10] = { trapCooldownRecoveryInc = 39, }, + [11] = { trapCooldownRecoveryInc = 40, }, + [12] = { trapCooldownRecoveryInc = 41, }, + [13] = { trapCooldownRecoveryInc = 42, }, + [14] = { trapCooldownRecoveryInc = 43, }, + [15] = { trapCooldownRecoveryInc = 44, }, + [16] = { trapCooldownRecoveryInc = 45, }, + [17] = { trapCooldownRecoveryInc = 46, }, + [18] = { trapCooldownRecoveryInc = 47, }, + [19] = { trapCooldownRecoveryInc = 48, }, + [20] = { trapCooldownRecoveryInc = 49, }, + [21] = { trapCooldownRecoveryInc = 50, }, + [22] = { trapCooldownRecoveryInc = 51, }, + [23] = { trapCooldownRecoveryInc = 52, }, + [24] = { trapCooldownRecoveryInc = 53, }, + [25] = { trapCooldownRecoveryInc = 54, }, + [26] = { trapCooldownRecoveryInc = 55, }, + [27] = { trapCooldownRecoveryInc = 56, }, + [28] = { trapCooldownRecoveryInc = 57, }, + [29] = { trapCooldownRecoveryInc = 58, }, + [30] = { trapCooldownRecoveryInc = 59, }, + } +} +gems["Trap and Mine Damage"] = { + support = true, + trap = true, + mine = true, + base = { + manaCostMore = 1.3, + trapThrowingSpeedMore = 0.9, + mineLayingSpeedMore = 0.9, + }, + quality = { + damageInc = 0.5, + }, + levels = { + [1] = { damageMore = 1.2, }, + [2] = { damageMore = 1.21, }, + [3] = { damageMore = 1.22, }, + [4] = { damageMore = 1.23, }, + [5] = { damageMore = 1.24, }, + [6] = { damageMore = 1.25, }, + [7] = { damageMore = 1.26, }, + [8] = { damageMore = 1.27, }, + [9] = { damageMore = 1.28, }, + [10] = { damageMore = 1.29, }, + [11] = { damageMore = 1.3, }, + [12] = { damageMore = 1.31, }, + [13] = { damageMore = 1.32, }, + [14] = { damageMore = 1.33, }, + [15] = { damageMore = 1.34, }, + [16] = { damageMore = 1.35, }, + [17] = { damageMore = 1.36, }, + [18] = { damageMore = 1.37, }, + [19] = { damageMore = 1.38, }, + [20] = { damageMore = 1.39, }, + [21] = { damageMore = 1.4, }, + [22] = { damageMore = 1.41, }, + [23] = { damageMore = 1.42, }, + [24] = { damageMore = 1.43, }, + [25] = { damageMore = 1.44, }, + [26] = { damageMore = 1.45, }, + [27] = { damageMore = 1.46, }, + [28] = { damageMore = 1.47, }, + [29] = { damageMore = 1.48, }, + [30] = { damageMore = 1.49, }, + } +} +gems["Void Manipulation"] = { + support = true, + chaos = true, + base = { + manaCostMore = 1.2, + elemInc = -25, + }, + quality = { + chaosInc = 0.5, + }, + levels = { + [1] = { chaosMore = 1.2, }, + [2] = { chaosMore = 1.21, }, + [3] = { chaosMore = 1.22, }, + [4] = { chaosMore = 1.23, }, + [5] = { chaosMore = 1.24, }, + [6] = { chaosMore = 1.25, }, + [7] = { chaosMore = 1.26, }, + [8] = { chaosMore = 1.27, }, + [9] = { chaosMore = 1.28, }, + [10] = { chaosMore = 1.29, }, + [11] = { chaosMore = 1.3, }, + [12] = { chaosMore = 1.31, }, + [13] = { chaosMore = 1.32, }, + [14] = { chaosMore = 1.33, }, + [15] = { chaosMore = 1.34, }, + [16] = { chaosMore = 1.35, }, + [17] = { chaosMore = 1.36, }, + [18] = { chaosMore = 1.37, }, + [19] = { chaosMore = 1.38, }, + [20] = { chaosMore = 1.39, }, + [21] = { chaosMore = 1.4, }, + [22] = { chaosMore = 1.41, }, + [23] = { chaosMore = 1.42, }, + [24] = { chaosMore = 1.43, }, + [25] = { chaosMore = 1.44, }, + [26] = { chaosMore = 1.45, }, + [27] = { chaosMore = 1.46, }, + [28] = { chaosMore = 1.47, }, + [29] = { chaosMore = 1.48, }, + [30] = { chaosMore = 1.49, }, + } +} \ No newline at end of file diff --git a/Gems/sup_int.lua b/Gems/sup_int.lua new file mode 100644 index 00000000..c3a0acf9 --- /dev/null +++ b/Gems/sup_int.lua @@ -0,0 +1,850 @@ +local gems = ... + +gems["Added Chaos Damage"] = { + support = true, + chaos = true, + base = { + manaCostMore = 1.3, + }, + quality = { + chaosInc = 0.5, + }, + levels = { + [1] = { chaosMin = 18, chaosMax = 26, }, + [2] = { chaosMin = 21, chaosMax = 32, }, + [3] = { chaosMin = 24, chaosMax = 36, }, + [4] = { chaosMin = 27, chaosMax = 41, }, + [5] = { chaosMin = 31, chaosMax = 46, }, + [6] = { chaosMin = 35, chaosMax = 52, }, + [7] = { chaosMin = 39, chaosMax = 59, }, + [8] = { chaosMin = 44, chaosMax = 67, }, + [9] = { chaosMin = 50, chaosMax = 75, }, + [10] = { chaosMin = 56, chaosMax = 84, }, + [11] = { chaosMin = 63, chaosMax = 94, }, + [12] = { chaosMin = 71, chaosMax = 106, }, + [13] = { chaosMin = 79, chaosMax = 118, }, + [14] = { chaosMin = 88, chaosMax = 132, }, + [15] = { chaosMin = 99, chaosMax = 148, }, + [16] = { chaosMin = 110, chaosMax = 165, }, + [17] = { chaosMin = 123, chaosMax = 185, }, + [18] = { chaosMin = 137, chaosMax = 206, }, + [19] = { chaosMin = 153, chaosMax = 229, }, + [20] = { chaosMin = 170, chaosMax = 256, }, + [21] = { chaosMin = 190, chaosMax = 284, }, + [22] = { chaosMin = 211, chaosMax = 316, }, + [23] = { chaosMin = 234, chaosMax = 352, }, + [24] = { chaosMin = 260, chaosMax = 391, }, + [25] = { chaosMin = 289, chaosMax = 434, }, + [26] = { chaosMin = 321, chaosMax = 482, }, + [27] = { chaosMin = 356, chaosMax = 534, }, + [28] = { chaosMin = 395, chaosMax = 592, }, + [29] = { chaosMin = 438, chaosMax = 657, }, + [30] = { chaosMin = 485, chaosMax = 728, }, + } +} +gems["Added Lightning Damage"] = { + support = true, + lightning = true, + base = { + manaCostMore = 1.3, + }, + quality = { + lightningInc = 0.5, + }, + levels = { + [1] = { lightningMin = 1, lightningMax = 8, }, + [2] = { lightningMin = 1, lightningMax = 9, }, + [3] = { lightningMin = 1, lightningMax = 12, }, + [4] = { lightningMin = 1, lightningMax = 16, }, + [5] = { lightningMin = 1, lightningMax = 22, }, + [6] = { lightningMin = 1, lightningMax = 28, }, + [7] = { lightningMin = 2, lightningMax = 36, }, + [8] = { lightningMin = 2, lightningMax = 47, }, + [9] = { lightningMin = 3, lightningMax = 59, }, + [10] = { lightningMin = 4, lightningMax = 70, }, + [11] = { lightningMin = 4, lightningMax = 83, }, + [12] = { lightningMin = 5, lightningMax = 98, }, + [13] = { lightningMin = 6, lightningMax = 116, }, + [14] = { lightningMin = 7, lightningMax = 136, }, + [15] = { lightningMin = 8, lightningMax = 159, }, + [16] = { lightningMin = 10, lightningMax = 186, }, + [17] = { lightningMin = 11, lightningMax = 218, }, + [18] = { lightningMin = 13, lightningMax = 253, }, + [19] = { lightningMin = 16, lightningMax = 295, }, + [20] = { lightningMin = 18, lightningMax = 342, }, + [21] = { lightningMin = 20, lightningMax = 378, }, + [22] = { lightningMin = 22, lightningMax = 417, }, + [23] = { lightningMin = 24, lightningMax = 459, }, + [24] = { lightningMin = 27, lightningMax = 506, }, + [25] = { lightningMin = 29, lightningMax = 557, }, + [26] = { lightningMin = 32, lightningMax = 614, }, + [27] = { lightningMin = 36, lightningMax = 675, }, + [28] = { lightningMin = 39, lightningMax = 743, }, + [29] = { lightningMin = 43, lightningMax = 816, }, + [30] = { lightningMin = 47, lightningMax = 897, }, + } +} +gems["Blasphemy"] = { + unsupported = true, +} +gems["Cast When Stunned"] = { + unsupported = true, +} +gems["Chance to Ignite"] = { + support = true, + fire = true, + base = { + manaCostMore = 1.1, + }, + quality = { + degen_fireInc = 0.5, + }, + levels = { + [1] = { igniteChance = 30, }, + [2] = { igniteChance = 31, }, + [3] = { igniteChance = 32, }, + [4] = { igniteChance = 33, }, + [5] = { igniteChance = 34, }, + [6] = { igniteChance = 35, }, + [7] = { igniteChance = 36, }, + [8] = { igniteChance = 37, }, + [9] = { igniteChance = 38, }, + [10] = { igniteChance = 39, }, + [11] = { igniteChance = 40, }, + [12] = { igniteChance = 41, }, + [13] = { igniteChance = 42, }, + [14] = { igniteChance = 43, }, + [15] = { igniteChance = 44, }, + [16] = { igniteChance = 45, }, + [17] = { igniteChance = 46, }, + [18] = { igniteChance = 47, }, + [19] = { igniteChance = 48, }, + [20] = { igniteChance = 49, }, + [21] = { igniteChance = 50, }, + [22] = { igniteChance = 51, }, + [23] = { igniteChance = 52, }, + [24] = { igniteChance = 53, }, + [25] = { igniteChance = 54, }, + [26] = { igniteChance = 55, }, + [27] = { igniteChance = 56, }, + [28] = { igniteChance = 57, }, + [29] = { igniteChance = 58, }, + [30] = { igniteChance = 59, }, + } +} +gems["Concentrated Effect"] = { + support = true, + aoe = true, + base = { + manaCostMore = 1.4, + aoeRadiusMore = 0.75, + }, + quality = { + aoe_damageInc = 0.5, + }, + levels = { + [1] = { aoe_damageMore = 1.4, }, + [2] = { aoe_damageMore = 1.41, }, + [3] = { aoe_damageMore = 1.42, }, + [4] = { aoe_damageMore = 1.43, }, + [5] = { aoe_damageMore = 1.44, }, + [6] = { aoe_damageMore = 1.45, }, + [7] = { aoe_damageMore = 1.46, }, + [8] = { aoe_damageMore = 1.47, }, + [9] = { aoe_damageMore = 1.48, }, + [10] = { aoe_damageMore = 1.49, }, + [11] = { aoe_damageMore = 1.5, }, + [12] = { aoe_damageMore = 1.51, }, + [13] = { aoe_damageMore = 1.52, }, + [14] = { aoe_damageMore = 1.53, }, + [15] = { aoe_damageMore = 1.54, }, + [16] = { aoe_damageMore = 1.55, }, + [17] = { aoe_damageMore = 1.56, }, + [18] = { aoe_damageMore = 1.57, }, + [19] = { aoe_damageMore = 1.58, }, + [20] = { aoe_damageMore = 1.59, }, + [21] = { aoe_damageMore = 1.6, }, + [22] = { aoe_damageMore = 1.61, }, + [23] = { aoe_damageMore = 1.62, }, + [24] = { aoe_damageMore = 1.63, }, + [25] = { aoe_damageMore = 1.64, }, + [26] = { aoe_damageMore = 1.65, }, + [27] = { aoe_damageMore = 1.66, }, + [28] = { aoe_damageMore = 1.67, }, + [29] = { aoe_damageMore = 1.68, }, + [30] = { aoe_damageMore = 1.69, }, + } +} +gems["Controlled Destruction"] = { + support = true, + spell = true, + base = { + manaCostMore = 1.3, + critChanceInc = -100, + }, + quality = { + spell_damageInc = 0.5, + }, + levels = { + [1] = { spell_damageMore = 1.25, }, + [2] = { spell_damageMore = 1.26, }, + [3] = { spell_damageMore = 1.27, }, + [4] = { spell_damageMore = 1.28, }, + [5] = { spell_damageMore = 1.29, }, + [6] = { spell_damageMore = 1.3, }, + [7] = { spell_damageMore = 1.31, }, + [8] = { spell_damageMore = 1.32, }, + [9] = { spell_damageMore = 1.33, }, + [10] = { spell_damageMore = 1.34, }, + [11] = { spell_damageMore = 1.35, }, + [12] = { spell_damageMore = 1.36, }, + [13] = { spell_damageMore = 1.37, }, + [14] = { spell_damageMore = 1.38, }, + [15] = { spell_damageMore = 1.39, }, + [16] = { spell_damageMore = 1.4, }, + [17] = { spell_damageMore = 1.41, }, + [18] = { spell_damageMore = 1.42, }, + [19] = { spell_damageMore = 1.43, }, + [20] = { spell_damageMore = 1.44, }, + [21] = { spell_damageMore = 1.45, }, + [22] = { spell_damageMore = 1.46, }, + [23] = { spell_damageMore = 1.47, }, + [24] = { spell_damageMore = 1.48, }, + [25] = { spell_damageMore = 1.49, }, + [26] = { spell_damageMore = 1.5, }, + [27] = { spell_damageMore = 1.51, }, + [28] = { spell_damageMore = 1.52, }, + [29] = { spell_damageMore = 1.53, }, + [30] = { spell_damageMore = 1.54, }, + } +} +gems["Curse on Hit"] = { + unsupported = true, +} +gems["Elemental Focus"] = { + support = true, + base = { + manaCostMore = 1.3, + }, + quality = { + elemInc = 0.5, + }, + levels = { + [1] = { elemMore = 1.3, }, + [2] = { elemMore = 1.31, }, + [3] = { elemMore = 1.32, }, + [4] = { elemMore = 1.33, }, + [5] = { elemMore = 1.34, }, + [6] = { elemMore = 1.35, }, + [7] = { elemMore = 1.36, }, + [8] = { elemMore = 1.37, }, + [9] = { elemMore = 1.38, }, + [10] = { elemMore = 1.39, }, + [11] = { elemMore = 1.4, }, + [12] = { elemMore = 1.41, }, + [13] = { elemMore = 1.42, }, + [14] = { elemMore = 1.43, }, + [15] = { elemMore = 1.44, }, + [16] = { elemMore = 1.45, }, + [17] = { elemMore = 1.46, }, + [18] = { elemMore = 1.47, }, + [19] = { elemMore = 1.48, }, + [20] = { elemMore = 1.49, }, + [21] = { elemMore = 1.5, }, + [22] = { elemMore = 1.51, }, + [23] = { elemMore = 1.52, }, + [24] = { elemMore = 1.53, }, + [25] = { elemMore = 1.54, }, + [26] = { elemMore = 1.55, }, + [27] = { elemMore = 1.56, }, + [28] = { elemMore = 1.57, }, + [29] = { elemMore = 1.58, }, + [30] = { elemMore = 1.59, }, + } +} +gems["Elemental Proliferation"] = { + support = true, + aoe = true, + fire = true, + cold = true, + lightning = true, + base = { + manaCostMore = 1.4, + }, + quality = { + ignite_durationInc = 0.5, + chill_durationInc = 0.5, + freeze_durationInc = 0.5, + shock_durationInc = 0.5, + }, + levels = { + [1] = { damageMore = 0.7, }, + [2] = { damageMore = 0.7, }, + [3] = { damageMore = 0.71, }, + [4] = { damageMore = 0.71, }, + [5] = { damageMore = 0.72, }, + [6] = { damageMore = 0.72, }, + [7] = { damageMore = 0.73, }, + [8] = { damageMore = 0.73, }, + [9] = { damageMore = 0.74, }, + [10] = { damageMore = 0.74, }, + [11] = { damageMore = 0.75, }, + [12] = { damageMore = 0.75, }, + [13] = { damageMore = 0.76, }, + [14] = { damageMore = 0.76, }, + [15] = { damageMore = 0.77, }, + [16] = { damageMore = 0.77, }, + [17] = { damageMore = 0.78, }, + [18] = { damageMore = 0.78, }, + [19] = { damageMore = 0.79, }, + [20] = { damageMore = 0.79, }, + [21] = { damageMore = 0.8, }, + [22] = { damageMore = 0.8, }, + [23] = { damageMore = 0.81, }, + [24] = { damageMore = 0.81, }, + [25] = { damageMore = 0.82, }, + [26] = { damageMore = 0.82, }, + [27] = { damageMore = 0.83, }, + [28] = { damageMore = 0.83, }, + [29] = { damageMore = 0.84, }, + [30] = { damageMore = 0.84, }, + } +} +gems["Enlighten"] = { + support = true, + base = { + }, + quality = { + }, + levels = { + [1] = { manaCostMore = 1, }, + [2] = { manaCostMore = 0.96, }, + [3] = { manaCostMore = 0.92, }, + [4] = { manaCostMore = 0.88, }, + [5] = { manaCostMore = 0.84, }, + [6] = { manaCostMore = 0.8, }, + [7] = { manaCostMore = 0.76, }, + [8] = { manaCostMore = 0.72, }, + [9] = { manaCostMore = 0.68, }, + [10] = { manaCostMore = 0.64, }, + } +} +gems["Faster Casting"] = { + support = true, + spell = true, + base = { + manaCostMore = 1.2, + }, + quality = { + castSpeedInc = 0.5, + }, + levels = { + [1] = { castSpeedInc = 20, }, + [2] = { castSpeedInc = 21, }, + [3] = { castSpeedInc = 22, }, + [4] = { castSpeedInc = 23, }, + [5] = { castSpeedInc = 24, }, + [6] = { castSpeedInc = 25, }, + [7] = { castSpeedInc = 26, }, + [8] = { castSpeedInc = 27, }, + [9] = { castSpeedInc = 28, }, + [10] = { castSpeedInc = 29, }, + [11] = { castSpeedInc = 30, }, + [12] = { castSpeedInc = 31, }, + [13] = { castSpeedInc = 32, }, + [14] = { castSpeedInc = 33, }, + [15] = { castSpeedInc = 34, }, + [16] = { castSpeedInc = 35, }, + [17] = { castSpeedInc = 36, }, + [18] = { castSpeedInc = 37, }, + [19] = { castSpeedInc = 38, }, + [20] = { castSpeedInc = 39, }, + [21] = { castSpeedInc = 40, }, + [22] = { castSpeedInc = 41, }, + [23] = { castSpeedInc = 42, }, + [24] = { castSpeedInc = 43, }, + [25] = { castSpeedInc = 44, }, + [26] = { castSpeedInc = 45, }, + [27] = { castSpeedInc = 46, }, + [28] = { castSpeedInc = 47, }, + [29] = { castSpeedInc = 48, }, + [30] = { castSpeedInc = 49, }, + } +} +gems["Increased Area of Effect"] = { + support = true, + aoe = true, + base = { + manaCostMore = 1.4, + }, + quality = { + aoe_damageInc = 0.5, + }, + levels = { + [1] = { aoeRadiusInc = 20, }, + [2] = { aoeRadiusInc = 21, }, + [3] = { aoeRadiusInc = 22, }, + [4] = { aoeRadiusInc = 23, }, + [5] = { aoeRadiusInc = 24, }, + [6] = { aoeRadiusInc = 25, }, + [7] = { aoeRadiusInc = 26, }, + [8] = { aoeRadiusInc = 27, }, + [9] = { aoeRadiusInc = 28, }, + [10] = { aoeRadiusInc = 29, }, + [11] = { aoeRadiusInc = 30, }, + [12] = { aoeRadiusInc = 31, }, + [13] = { aoeRadiusInc = 32, }, + [14] = { aoeRadiusInc = 33, }, + [15] = { aoeRadiusInc = 34, }, + [16] = { aoeRadiusInc = 35, }, + [17] = { aoeRadiusInc = 36, }, + [18] = { aoeRadiusInc = 37, }, + [19] = { aoeRadiusInc = 38, }, + [20] = { aoeRadiusInc = 39, }, + [21] = { aoeRadiusInc = 40, }, + [22] = { aoeRadiusInc = 41, }, + [23] = { aoeRadiusInc = 42, }, + [24] = { aoeRadiusInc = 43, }, + [25] = { aoeRadiusInc = 44, }, + [26] = { aoeRadiusInc = 45, }, + [27] = { aoeRadiusInc = 46, }, + [28] = { aoeRadiusInc = 47, }, + [29] = { aoeRadiusInc = 48, }, + [30] = { aoeRadiusInc = 49, }, + } +} +gems["Increased Critical Damage"] = { + support = true, + base = { + manaCostMore = 1.3, + }, + quality = { + critMultiplier = 0.5, + }, + levels = { + [1] = { critMultiplier = 75, }, + [2] = { critMultiplier = 76, }, + [3] = { critMultiplier = 78, }, + [4] = { critMultiplier = 79, }, + [5] = { critMultiplier = 81, }, + [6] = { critMultiplier = 82, }, + [7] = { critMultiplier = 84, }, + [8] = { critMultiplier = 85, }, + [9] = { critMultiplier = 87, }, + [10] = { critMultiplier = 88, }, + [11] = { critMultiplier = 90, }, + [12] = { critMultiplier = 91, }, + [13] = { critMultiplier = 93, }, + [14] = { critMultiplier = 94, }, + [15] = { critMultiplier = 96, }, + [16] = { critMultiplier = 97, }, + [17] = { critMultiplier = 99, }, + [18] = { critMultiplier = 100, }, + [19] = { critMultiplier = 102, }, + [20] = { critMultiplier = 103, }, + [21] = { critMultiplier = 105, }, + [22] = { critMultiplier = 106, }, + [23] = { critMultiplier = 108, }, + [24] = { critMultiplier = 109, }, + [25] = { critMultiplier = 111, }, + [26] = { critMultiplier = 112, }, + [27] = { critMultiplier = 114, }, + [28] = { critMultiplier = 115, }, + [29] = { critMultiplier = 117, }, + [30] = { critMultiplier = 118, }, + } +} +gems["Increased Critical Strikes"] = { + support = true, + base = { + manaCostMore = 1.15, + }, + quality = { + critChanceInc = 1, + }, + levels = { + [1] = { critChanceInc = 50, critChanceBase = 1, }, + [2] = { critChanceInc = 52, critChanceBase = 1, }, + [3] = { critChanceInc = 54, critChanceBase = 1.1, }, + [4] = { critChanceInc = 56, critChanceBase = 1.1, }, + [5] = { critChanceInc = 58, critChanceBase = 1.2, }, + [6] = { critChanceInc = 60, critChanceBase = 1.2, }, + [7] = { critChanceInc = 62, critChanceBase = 1.3, }, + [8] = { critChanceInc = 64, critChanceBase = 1.3, }, + [9] = { critChanceInc = 66, critChanceBase = 1.4, }, + [10] = { critChanceInc = 68, critChanceBase = 1.4, }, + [11] = { critChanceInc = 70, critChanceBase = 1.5, }, + [12] = { critChanceInc = 72, critChanceBase = 1.5, }, + [13] = { critChanceInc = 74, critChanceBase = 1.6, }, + [14] = { critChanceInc = 76, critChanceBase = 1.6, }, + [15] = { critChanceInc = 78, critChanceBase = 1.7, }, + [16] = { critChanceInc = 80, critChanceBase = 1.7, }, + [17] = { critChanceInc = 82, critChanceBase = 1.8, }, + [18] = { critChanceInc = 84, critChanceBase = 1.8, }, + [19] = { critChanceInc = 86, critChanceBase = 1.9, }, + [20] = { critChanceInc = 88, critChanceBase = 1.9, }, + [21] = { critChanceInc = 90, critChanceBase = 2, }, + [22] = { critChanceInc = 92, critChanceBase = 2, }, + [23] = { critChanceInc = 94, critChanceBase = 2.1, }, + [24] = { critChanceInc = 96, critChanceBase = 2.1, }, + [25] = { critChanceInc = 98, critChanceBase = 2.2, }, + [26] = { critChanceInc = 100, critChanceBase = 2.2, }, + [27] = { critChanceInc = 102, critChanceBase = 2.3, }, + [28] = { critChanceInc = 104, critChanceBase = 2.3, }, + [29] = { critChanceInc = 106, critChanceBase = 2.4, }, + [30] = { critChanceInc = 108, critChanceBase = 2.4, }, + } +} +gems["Innervate"] = { + support = true, + lightning = true, + base = { + manaCostMore = 1.1, + shockChance = 15, + }, + quality = { + shock_durationInc = 1.5, + }, + levels = { + [1] = { }, + [2] = { }, + [3] = { }, + [4] = { }, + [5] = { }, + [6] = { }, + [7] = { }, + [8] = { }, + [9] = { }, + [10] = { }, + [11] = { }, + [12] = { }, + [13] = { }, + [14] = { }, + [15] = { }, + [16] = { }, + [17] = { }, + [18] = { }, + [19] = { }, + [20] = { }, + [21] = { }, + [22] = { }, + [23] = { }, + [24] = { }, + [25] = { }, + [26] = { }, + [27] = { }, + [28] = { }, + [29] = { }, + [30] = { }, + } +} +gems["Item Rarity"] = { + support = true, + base = { + }, + quality = { + lootRarityInc = 0.5, + }, + levels = { + [1] = { lootRarityInc = 40, }, + [2] = { lootRarityInc = 41, }, + [3] = { lootRarityInc = 42, }, + [4] = { lootRarityInc = 43, }, + [5] = { lootRarityInc = 44, }, + [6] = { lootRarityInc = 45, }, + [7] = { lootRarityInc = 46, }, + [8] = { lootRarityInc = 47, }, + [9] = { lootRarityInc = 48, }, + [10] = { lootRarityInc = 49, }, + [11] = { lootRarityInc = 50, }, + [12] = { lootRarityInc = 51, }, + [13] = { lootRarityInc = 52, }, + [14] = { lootRarityInc = 53, }, + [15] = { lootRarityInc = 54, }, + [16] = { lootRarityInc = 55, }, + [17] = { lootRarityInc = 56, }, + [18] = { lootRarityInc = 57, }, + [19] = { lootRarityInc = 58, }, + [20] = { lootRarityInc = 59, }, + [21] = { lootRarityInc = 60, }, + [22] = { lootRarityInc = 61, }, + [23] = { lootRarityInc = 62, }, + [24] = { lootRarityInc = 63, }, + [25] = { lootRarityInc = 64, }, + [26] = { lootRarityInc = 65, }, + [27] = { lootRarityInc = 66, }, + [28] = { lootRarityInc = 67, }, + [29] = { lootRarityInc = 68, }, + [30] = { lootRarityInc = 69, }, + } +} +gems["Lightning Penetration"] = { + support = true, + lightning = true, + base = { + manaCostMore = 1.4, + }, + quality = { + lightningInc = 0.5, + }, + levels = { + [1] = { lightningPen = 18, }, + [2] = { lightningPen = 19, }, + [3] = { lightningPen = 20, }, + [4] = { lightningPen = 21, }, + [5] = { lightningPen = 22, }, + [6] = { lightningPen = 23, }, + [7] = { lightningPen = 24, }, + [8] = { lightningPen = 25, }, + [9] = { lightningPen = 26, }, + [10] = { lightningPen = 27, }, + [11] = { lightningPen = 28, }, + [12] = { lightningPen = 29, }, + [13] = { lightningPen = 30, }, + [14] = { lightningPen = 31, }, + [15] = { lightningPen = 32, }, + [16] = { lightningPen = 33, }, + [17] = { lightningPen = 34, }, + [18] = { lightningPen = 35, }, + [19] = { lightningPen = 36, }, + [20] = { lightningPen = 37, }, + [21] = { lightningPen = 38, }, + [22] = { lightningPen = 39, }, + [23] = { lightningPen = 40, }, + [24] = { lightningPen = 41, }, + [25] = { lightningPen = 42, }, + [26] = { lightningPen = 43, }, + [27] = { lightningPen = 44, }, + [28] = { lightningPen = 45, }, + [29] = { lightningPen = 46, }, + [30] = { lightningPen = 47, }, + } +} +gems["Minefield"] = { + support = true, + mine = true, + base = { + manaCostMore = 1.6, + }, + quality = { + mineDetonationRadiusInc = 1, + }, + levels = { + [1] = { mine_damageMore = 0.6, }, + [2] = { mine_damageMore = 0.61, }, + [3] = { mine_damageMore = 0.62, }, + [4] = { mine_damageMore = 0.63, }, + [5] = { mine_damageMore = 0.64, }, + [6] = { mine_damageMore = 0.65, }, + [7] = { mine_damageMore = 0.66, }, + [8] = { mine_damageMore = 0.67, }, + [9] = { mine_damageMore = 0.68, }, + [10] = { mine_damageMore = 0.69, }, + [11] = { mine_damageMore = 0.7, }, + [12] = { mine_damageMore = 0.71, }, + [13] = { mine_damageMore = 0.72, }, + [14] = { mine_damageMore = 0.73, }, + [15] = { mine_damageMore = 0.74, }, + [16] = { mine_damageMore = 0.75, }, + [17] = { mine_damageMore = 0.76, }, + [18] = { mine_damageMore = 0.77, }, + [19] = { mine_damageMore = 0.78, }, + [20] = { mine_damageMore = 0.79, }, + [21] = { mine_damageMore = 0.8, }, + [22] = { mine_damageMore = 0.81, }, + [23] = { mine_damageMore = 0.82, }, + [24] = { mine_damageMore = 0.83, }, + [25] = { mine_damageMore = 0.84, }, + [26] = { mine_damageMore = 0.85, }, + [27] = { mine_damageMore = 0.86, }, + [28] = { mine_damageMore = 0.87, }, + [29] = { mine_damageMore = 0.88, }, + [30] = { mine_damageMore = 0.89, }, + } +} +gems["Minion and Totem Elemental Resistance"] = { + unsupported = true, +} +gems["Minion Damage"] = { + unsupported = true, +} +gems["Minion Life"] = { + unsupported = true, +} +gems["Minion Speed"] = { + unsupported = true, +} +gems["Physical to Lightning"] = { + support = true, + lightning = true, + base = { + manaCostMore = 1.1, + physicalConvertTolightning = 50, + }, + quality = { + physicalInc = 0.5, + lightningInc = 0.5, + }, + levels = { + [1] = { physicalGainAslightning = 10, }, + [2] = { physicalGainAslightning = 11, }, + [3] = { physicalGainAslightning = 12, }, + [4] = { physicalGainAslightning = 13, }, + [5] = { physicalGainAslightning = 14, }, + [6] = { physicalGainAslightning = 15, }, + [7] = { physicalGainAslightning = 16, }, + [8] = { physicalGainAslightning = 17, }, + [9] = { physicalGainAslightning = 18, }, + [10] = { physicalGainAslightning = 19, }, + [11] = { physicalGainAslightning = 20, }, + [12] = { physicalGainAslightning = 21, }, + [13] = { physicalGainAslightning = 22, }, + [14] = { physicalGainAslightning = 23, }, + [15] = { physicalGainAslightning = 24, }, + [16] = { physicalGainAslightning = 25, }, + [17] = { physicalGainAslightning = 26, }, + [18] = { physicalGainAslightning = 27, }, + [19] = { physicalGainAslightning = 28, }, + [20] = { physicalGainAslightning = 29, }, + [21] = { physicalGainAslightning = 30, }, + [22] = { physicalGainAslightning = 31, }, + [23] = { physicalGainAslightning = 32, }, + [24] = { physicalGainAslightning = 33, }, + [25] = { physicalGainAslightning = 34, }, + [26] = { physicalGainAslightning = 35, }, + [27] = { physicalGainAslightning = 36, }, + [28] = { physicalGainAslightning = 37, }, + [29] = { physicalGainAslightning = 38, }, + [30] = { physicalGainAslightning = 39, }, + } +} +gems["Power Charge On Critical"] = { + support = true, + base = { + manaCostMore = 1.1, + }, + quality = { + critChanceInc = 1, + }, + levels = { + [1] = { }, + [2] = { }, + [3] = { }, + [4] = { }, + [5] = { }, + [6] = { }, + [7] = { }, + [8] = { }, + [9] = { }, + [10] = { }, + [11] = { }, + [12] = { }, + [13] = { }, + [14] = { }, + [15] = { }, + [16] = { }, + [17] = { }, + [18] = { }, + [19] = { }, + [20] = { }, + [21] = { }, + [22] = { }, + [23] = { }, + [24] = { }, + [25] = { }, + [26] = { }, + [27] = { }, + [28] = { }, + [29] = { }, + [30] = { }, + } +} +gems["Remote Mine"] = { + support = true, + mine = true, + addFlags = { + mine = true, + showAverage = true, + }, + base = { + manaCostMore = 1.5, + }, + quality = { + mineLayingSpeedInc = 0.5, + }, + levels = { + [1] = { mine_damageMore = 1.3, }, + [2] = { mine_damageMore = 1.31, }, + [3] = { mine_damageMore = 1.32, }, + [4] = { mine_damageMore = 1.33, }, + [5] = { mine_damageMore = 1.34, }, + [6] = { mine_damageMore = 1.35, }, + [7] = { mine_damageMore = 1.36, }, + [8] = { mine_damageMore = 1.37, }, + [9] = { mine_damageMore = 1.38, }, + [10] = { mine_damageMore = 1.39, }, + [11] = { mine_damageMore = 1.4, }, + [12] = { mine_damageMore = 1.41, }, + [13] = { mine_damageMore = 1.42, }, + [14] = { mine_damageMore = 1.43, }, + [15] = { mine_damageMore = 1.44, }, + [16] = { mine_damageMore = 1.45, }, + [17] = { mine_damageMore = 1.46, }, + [18] = { mine_damageMore = 1.47, }, + [19] = { mine_damageMore = 1.48, }, + [20] = { mine_damageMore = 1.49, }, + [21] = { mine_damageMore = 1.5, }, + [22] = { mine_damageMore = 1.51, }, + [23] = { mine_damageMore = 1.52, }, + [24] = { mine_damageMore = 1.53, }, + [25] = { mine_damageMore = 1.54, }, + [26] = { mine_damageMore = 1.55, }, + [27] = { mine_damageMore = 1.56, }, + [28] = { mine_damageMore = 1.57, }, + [29] = { mine_damageMore = 1.58, }, + [30] = { mine_damageMore = 1.59, }, + } +} +gems["Spell Echo"] = { + support = true, + spell = true, + base = { + manaCostMore = 1.4, + spell_damageMore = 0.9, + }, + quality = { + spell_damageInc = 0.5, + }, + levels = { + [1] = { castSpeedMore = 1.51, }, + [2] = { castSpeedMore = 1.52, }, + [3] = { castSpeedMore = 1.53, }, + [4] = { castSpeedMore = 1.54, }, + [5] = { castSpeedMore = 1.55, }, + [6] = { castSpeedMore = 1.56, }, + [7] = { castSpeedMore = 1.57, }, + [8] = { castSpeedMore = 1.58, }, + [9] = { castSpeedMore = 1.59, }, + [10] = { castSpeedMore = 1.6, }, + [11] = { castSpeedMore = 1.61, }, + [12] = { castSpeedMore = 1.62, }, + [13] = { castSpeedMore = 1.63, }, + [14] = { castSpeedMore = 1.64, }, + [15] = { castSpeedMore = 1.65, }, + [16] = { castSpeedMore = 1.66, }, + [17] = { castSpeedMore = 1.67, }, + [18] = { castSpeedMore = 1.68, }, + [19] = { castSpeedMore = 1.69, }, + [20] = { castSpeedMore = 1.7, }, + [21] = { castSpeedMore = 1.71, }, + [22] = { castSpeedMore = 1.72, }, + [23] = { castSpeedMore = 1.73, }, + [24] = { castSpeedMore = 1.74, }, + [25] = { castSpeedMore = 1.75, }, + [26] = { castSpeedMore = 1.76, }, + [27] = { castSpeedMore = 1.77, }, + [28] = { castSpeedMore = 1.78, }, + [29] = { castSpeedMore = 1.79, }, + [30] = { castSpeedMore = 1.8, }, + } +} \ No newline at end of file diff --git a/Gems/sup_str.lua b/Gems/sup_str.lua new file mode 100644 index 00000000..acd794f9 --- /dev/null +++ b/Gems/sup_str.lua @@ -0,0 +1,1049 @@ +local gems = ... + +gems["Added Fire Damage"] = { + support = true, + fire = true, + base = { + manaCostMore = 1.2, + }, + quality = { + fireInc = 0.5, + }, + levels = { + [1] = { physicalGainAsfire = 25, }, + [2] = { physicalGainAsfire = 26, }, + [3] = { physicalGainAsfire = 27, }, + [4] = { physicalGainAsfire = 28, }, + [5] = { physicalGainAsfire = 29, }, + [6] = { physicalGainAsfire = 30, }, + [7] = { physicalGainAsfire = 31, }, + [8] = { physicalGainAsfire = 32, }, + [9] = { physicalGainAsfire = 33, }, + [10] = { physicalGainAsfire = 34, }, + [11] = { physicalGainAsfire = 35, }, + [12] = { physicalGainAsfire = 36, }, + [13] = { physicalGainAsfire = 37, }, + [14] = { physicalGainAsfire = 38, }, + [15] = { physicalGainAsfire = 39, }, + [16] = { physicalGainAsfire = 40, }, + [17] = { physicalGainAsfire = 41, }, + [18] = { physicalGainAsfire = 42, }, + [19] = { physicalGainAsfire = 43, }, + [20] = { physicalGainAsfire = 44, }, + [21] = { physicalGainAsfire = 45, }, + [22] = { physicalGainAsfire = 46, }, + [23] = { physicalGainAsfire = 47, }, + [24] = { physicalGainAsfire = 48, }, + [25] = { physicalGainAsfire = 49, }, + [26] = { physicalGainAsfire = 50, }, + [27] = { physicalGainAsfire = 51, }, + [28] = { physicalGainAsfire = 52, }, + [29] = { physicalGainAsfire = 53, }, + [30] = { physicalGainAsfire = 54, }, + } +} +gems["Blood Magic"] = { + support = true, + base = { + }, + quality = { + skill_costInc = -0.5, + }, + levels = { + [1] = { manaCostMore = 2.45, }, + [2] = { manaCostMore = 2.42, }, + [3] = { manaCostMore = 2.39, }, + [4] = { manaCostMore = 2.37, }, + [5] = { manaCostMore = 2.34, }, + [6] = { manaCostMore = 2.32, }, + [7] = { manaCostMore = 2.29, }, + [8] = { manaCostMore = 2.26, }, + [9] = { manaCostMore = 2.24, }, + [10] = { manaCostMore = 2.21, }, + [11] = { manaCostMore = 2.18, }, + [12] = { manaCostMore = 2.16, }, + [13] = { manaCostMore = 2.13, }, + [14] = { manaCostMore = 2.11, }, + [15] = { manaCostMore = 2.08, }, + [16] = { manaCostMore = 2.05, }, + [17] = { manaCostMore = 2.03, }, + [18] = { manaCostMore = 2, }, + [19] = { manaCostMore = 1.97, }, + [20] = { manaCostMore = 1.96, }, + [21] = { manaCostMore = 1.93, }, + [22] = { manaCostMore = 1.9, }, + [23] = { manaCostMore = 1.87, }, + [24] = { manaCostMore = 1.84, }, + [25] = { manaCostMore = 1.81, }, + [26] = { manaCostMore = 1.78, }, + [27] = { manaCostMore = 1.75, }, + [28] = { manaCostMore = 1.72, }, + [29] = { manaCostMore = 1.69, }, + [30] = { manaCostMore = 1.66, }, + } +} +gems["Bloodlust"] = { + support = true, + attack = true, + melee = true, + base = { + manaCostMore = 1.25, + }, + quality = { + condMod_EnemyBleeding_melee_damageInc = 0.5, + }, + levels = { + [1] = { condMod_EnemyBleeding_melee_physicalMore = 1.4, }, + [2] = { condMod_EnemyBleeding_melee_physicalMore = 1.41, }, + [3] = { condMod_EnemyBleeding_melee_physicalMore = 1.42, }, + [4] = { condMod_EnemyBleeding_melee_physicalMore = 1.43, }, + [5] = { condMod_EnemyBleeding_melee_physicalMore = 1.44, }, + [6] = { condMod_EnemyBleeding_melee_physicalMore = 1.45, }, + [7] = { condMod_EnemyBleeding_melee_physicalMore = 1.46, }, + [8] = { condMod_EnemyBleeding_melee_physicalMore = 1.47, }, + [9] = { condMod_EnemyBleeding_melee_physicalMore = 1.48, }, + [10] = { condMod_EnemyBleeding_melee_physicalMore = 1.49, }, + [11] = { condMod_EnemyBleeding_melee_physicalMore = 1.5, }, + [12] = { condMod_EnemyBleeding_melee_physicalMore = 1.51, }, + [13] = { condMod_EnemyBleeding_melee_physicalMore = 1.52, }, + [14] = { condMod_EnemyBleeding_melee_physicalMore = 1.53, }, + [15] = { condMod_EnemyBleeding_melee_physicalMore = 1.54, }, + [16] = { condMod_EnemyBleeding_melee_physicalMore = 1.55, }, + [17] = { condMod_EnemyBleeding_melee_physicalMore = 1.56, }, + [18] = { condMod_EnemyBleeding_melee_physicalMore = 1.57, }, + [19] = { condMod_EnemyBleeding_melee_physicalMore = 1.58, }, + [20] = { condMod_EnemyBleeding_melee_physicalMore = 1.59, }, + [21] = { condMod_EnemyBleeding_melee_physicalMore = 1.6, }, + [22] = { condMod_EnemyBleeding_melee_physicalMore = 1.61, }, + [23] = { condMod_EnemyBleeding_melee_physicalMore = 1.62, }, + [24] = { condMod_EnemyBleeding_melee_physicalMore = 1.63, }, + [25] = { condMod_EnemyBleeding_melee_physicalMore = 1.64, }, + [26] = { condMod_EnemyBleeding_melee_physicalMore = 1.65, }, + [27] = { condMod_EnemyBleeding_melee_physicalMore = 1.66, }, + [28] = { condMod_EnemyBleeding_melee_physicalMore = 1.67, }, + [29] = { condMod_EnemyBleeding_melee_physicalMore = 1.68, }, + [30] = { condMod_EnemyBleeding_melee_physicalMore = 1.69, }, + } +} +gems["Cast on Melee Kill"] = { + unsupported = true, +} +gems["Cast when Damage Taken"] = { + unsupported = true, +} +gems["Cold to Fire"] = { + support = true, + fire = true, + cold = true, + base = { + manaCostMore = 1.1, + coldConvertTofire = 50, + }, + quality = { + fireInc = 0.5, + coldInc = 0.5, + }, + levels = { + [1] = { coldGainAsfire = 10, }, + [2] = { coldGainAsfire = 11, }, + [3] = { coldGainAsfire = 12, }, + [4] = { coldGainAsfire = 13, }, + [5] = { coldGainAsfire = 14, }, + [6] = { coldGainAsfire = 15, }, + [7] = { coldGainAsfire = 16, }, + [8] = { coldGainAsfire = 17, }, + [9] = { coldGainAsfire = 18, }, + [10] = { coldGainAsfire = 19, }, + [11] = { coldGainAsfire = 20, }, + [12] = { coldGainAsfire = 21, }, + [13] = { coldGainAsfire = 22, }, + [14] = { coldGainAsfire = 23, }, + [15] = { coldGainAsfire = 24, }, + [16] = { coldGainAsfire = 25, }, + [17] = { coldGainAsfire = 26, }, + [18] = { coldGainAsfire = 27, }, + [19] = { coldGainAsfire = 28, }, + [20] = { coldGainAsfire = 29, }, + [21] = { coldGainAsfire = 30, }, + [22] = { coldGainAsfire = 31, }, + [23] = { coldGainAsfire = 32, }, + [24] = { coldGainAsfire = 33, }, + [25] = { coldGainAsfire = 34, }, + [26] = { coldGainAsfire = 35, }, + [27] = { coldGainAsfire = 36, }, + [28] = { coldGainAsfire = 37, }, + [29] = { coldGainAsfire = 38, }, + [30] = { coldGainAsfire = 39, }, + } +} +gems["Empower"] = { + support = true, + base = { + manaCostMore = 1.25, + }, + quality = { + }, + levels = { + [1] = { }, + [2] = { }, + [3] = { }, + [4] = { }, + [5] = { }, + [6] = { }, + [7] = { }, + [8] = { }, + [9] = { }, + [10] = { }, + } +} +gems["Endurance Charge on Melee Stun"] = { + support = true, + attack = true, + melee = true, + base = { + manaCostMore = 1.1, + }, + quality = { + stunEnemyDur = 1, + }, + levels = { + [1] = { stunEnemyThreshInc = -0, }, + [2] = { stunEnemyThreshInc = -1, }, + [3] = { stunEnemyThreshInc = -2, }, + [4] = { stunEnemyThreshInc = -3, }, + [5] = { stunEnemyThreshInc = -4, }, + [6] = { stunEnemyThreshInc = -5, }, + [7] = { stunEnemyThreshInc = -6, }, + [8] = { stunEnemyThreshInc = -7, }, + [9] = { stunEnemyThreshInc = -8, }, + [10] = { stunEnemyThreshInc = -9, }, + [11] = { stunEnemyThreshInc = -10, }, + [12] = { stunEnemyThreshInc = -11, }, + [13] = { stunEnemyThreshInc = -12, }, + [14] = { stunEnemyThreshInc = -13, }, + [15] = { stunEnemyThreshInc = -14, }, + [16] = { stunEnemyThreshInc = -15, }, + [17] = { stunEnemyThreshInc = -16, }, + [18] = { stunEnemyThreshInc = -17, }, + [19] = { stunEnemyThreshInc = -18, }, + [20] = { stunEnemyThreshInc = -19, }, + [21] = { stunEnemyThreshInc = -20, }, + [22] = { stunEnemyThreshInc = -21, }, + [23] = { stunEnemyThreshInc = -22, }, + [24] = { stunEnemyThreshInc = -23, }, + [25] = { stunEnemyThreshInc = -24, }, + [26] = { stunEnemyThreshInc = -25, }, + [27] = { stunEnemyThreshInc = -26, }, + [28] = { stunEnemyThreshInc = -27, }, + [29] = { stunEnemyThreshInc = -28, }, + [30] = { stunEnemyThreshInc = -29, }, + } +} +gems["Fire Penetration"] = { + support = true, + fire = true, + base = { + manaCostMore = 1.4, + }, + quality = { + fireInc = 0.5, + }, + levels = { + [1] = { firePen = 18, }, + [2] = { firePen = 19, }, + [3] = { firePen = 20, }, + [4] = { firePen = 21, }, + [5] = { firePen = 22, }, + [6] = { firePen = 23, }, + [7] = { firePen = 24, }, + [8] = { firePen = 25, }, + [9] = { firePen = 26, }, + [10] = { firePen = 27, }, + [11] = { firePen = 28, }, + [12] = { firePen = 29, }, + [13] = { firePen = 30, }, + [14] = { firePen = 31, }, + [15] = { firePen = 32, }, + [16] = { firePen = 33, }, + [17] = { firePen = 34, }, + [18] = { firePen = 35, }, + [19] = { firePen = 36, }, + [20] = { firePen = 37, }, + [21] = { firePen = 38, }, + [22] = { firePen = 39, }, + [23] = { firePen = 40, }, + [24] = { firePen = 41, }, + [25] = { firePen = 42, }, + [26] = { firePen = 43, }, + [27] = { firePen = 44, }, + [28] = { firePen = 45, }, + [29] = { firePen = 46, }, + [30] = { firePen = 47, }, + } +} +gems["Fortify"] = { + support = true, + attack = true, + melee = true, + base = { + manaCostMore = 1.1, + condBuff_Fortify = true, + }, + quality = { + fortifyDurationInc = 0.5, + }, + levels = { + [1] = { melee_physicalInc = 25, }, + [2] = { melee_physicalInc = 26, }, + [3] = { melee_physicalInc = 27, }, + [4] = { melee_physicalInc = 28, }, + [5] = { melee_physicalInc = 29, }, + [6] = { melee_physicalInc = 30, }, + [7] = { melee_physicalInc = 31, }, + [8] = { melee_physicalInc = 32, }, + [9] = { melee_physicalInc = 33, }, + [10] = { melee_physicalInc = 34, }, + [11] = { melee_physicalInc = 35, }, + [12] = { melee_physicalInc = 36, }, + [13] = { melee_physicalInc = 37, }, + [14] = { melee_physicalInc = 38, }, + [15] = { melee_physicalInc = 39, }, + [16] = { melee_physicalInc = 40, }, + [17] = { melee_physicalInc = 41, }, + [18] = { melee_physicalInc = 42, }, + [19] = { melee_physicalInc = 43, }, + [20] = { melee_physicalInc = 44, }, + [21] = { melee_physicalInc = 45, }, + [22] = { melee_physicalInc = 46, }, + [23] = { melee_physicalInc = 47, }, + [24] = { melee_physicalInc = 48, }, + [25] = { melee_physicalInc = 49, }, + [26] = { melee_physicalInc = 50, }, + [27] = { melee_physicalInc = 51, }, + [28] = { melee_physicalInc = 52, }, + [29] = { melee_physicalInc = 53, }, + [30] = { melee_physicalInc = 54, }, + } +} +gems["Generosity"] = { + unsupported = true, +} +gems["Increased Burning Damage"] = { + support = true, + fire = true, + base = { + manaCostMore = 1.2, + }, + quality = { + degen_fireInc = 0.5, + }, + levels = { + [1] = { degen_fireInc = 40, }, + [2] = { degen_fireInc = 41, }, + [3] = { degen_fireInc = 42, }, + [4] = { degen_fireInc = 43, }, + [5] = { degen_fireInc = 44, }, + [6] = { degen_fireInc = 45, }, + [7] = { degen_fireInc = 46, }, + [8] = { degen_fireInc = 47, }, + [9] = { degen_fireInc = 48, }, + [10] = { degen_fireInc = 49, }, + [11] = { degen_fireInc = 50, }, + [12] = { degen_fireInc = 51, }, + [13] = { degen_fireInc = 52, }, + [14] = { degen_fireInc = 53, }, + [15] = { degen_fireInc = 54, }, + [16] = { degen_fireInc = 55, }, + [17] = { degen_fireInc = 56, }, + [18] = { degen_fireInc = 57, }, + [19] = { degen_fireInc = 58, }, + [20] = { degen_fireInc = 59, }, + [21] = { degen_fireInc = 60, }, + [22] = { degen_fireInc = 61, }, + [23] = { degen_fireInc = 62, }, + [24] = { degen_fireInc = 63, }, + [25] = { degen_fireInc = 64, }, + [26] = { degen_fireInc = 65, }, + [27] = { degen_fireInc = 66, }, + [28] = { degen_fireInc = 67, }, + [29] = { degen_fireInc = 68, }, + [30] = { degen_fireInc = 69, }, + } +} +gems["Increased Duration"] = { + support = true, + base = { + manaCostMore = 1.4, + }, + quality = { + durationInc = 0.5, + }, + levels = { + [1] = { durationInc = 45, }, + [2] = { durationInc = 46, }, + [3] = { durationInc = 47, }, + [4] = { durationInc = 48, }, + [5] = { durationInc = 49, }, + [6] = { durationInc = 50, }, + [7] = { durationInc = 51, }, + [8] = { durationInc = 52, }, + [9] = { durationInc = 53, }, + [10] = { durationInc = 54, }, + [11] = { durationInc = 55, }, + [12] = { durationInc = 56, }, + [13] = { durationInc = 57, }, + [14] = { durationInc = 58, }, + [15] = { durationInc = 59, }, + [16] = { durationInc = 60, }, + [17] = { durationInc = 61, }, + [18] = { durationInc = 62, }, + [19] = { durationInc = 63, }, + [20] = { durationInc = 64, }, + [21] = { durationInc = 65, }, + [22] = { durationInc = 66, }, + [23] = { durationInc = 67, }, + [24] = { durationInc = 68, }, + [25] = { durationInc = 69, }, + [26] = { durationInc = 70, }, + [27] = { durationInc = 71, }, + [28] = { durationInc = 72, }, + [29] = { durationInc = 73, }, + [30] = { durationInc = 74, }, + } +} +gems["Iron Grip"] = { + support = true, + projectile = true, + base = { + ironGrip = true, + }, + quality = { + projectile_damageInc = 0.5, + }, + levels = { + [1] = { projectile_damageInc = 0, }, + [2] = { projectile_damageInc = 2, }, + [3] = { projectile_damageInc = 4, }, + [4] = { projectile_damageInc = 6, }, + [5] = { projectile_damageInc = 8, }, + [6] = { projectile_damageInc = 10, }, + [7] = { projectile_damageInc = 12, }, + [8] = { projectile_damageInc = 14, }, + [9] = { projectile_damageInc = 16, }, + [10] = { projectile_damageInc = 18, }, + [11] = { projectile_damageInc = 20, }, + [12] = { projectile_damageInc = 22, }, + [13] = { projectile_damageInc = 24, }, + [14] = { projectile_damageInc = 26, }, + [15] = { projectile_damageInc = 28, }, + [16] = { projectile_damageInc = 30, }, + [17] = { projectile_damageInc = 32, }, + [18] = { projectile_damageInc = 34, }, + [19] = { projectile_damageInc = 36, }, + [20] = { projectile_damageInc = 38, }, + [21] = { projectile_damageInc = 40, }, + [22] = { projectile_damageInc = 42, }, + [23] = { projectile_damageInc = 44, }, + [24] = { projectile_damageInc = 46, }, + [25] = { projectile_damageInc = 48, }, + [26] = { projectile_damageInc = 50, }, + [27] = { projectile_damageInc = 52, }, + [28] = { projectile_damageInc = 54, }, + [29] = { projectile_damageInc = 56, }, + [30] = { projectile_damageInc = 58, }, + } +} +gems["Iron Will"] = { + support = true, + spell = true, + base = { + ironWill = true, + }, + quality = { + spell_damageInc = 0.5, + }, + levels = { + [1] = { spell_damageInc = 0, }, + [2] = { spell_damageInc = 2, }, + [3] = { spell_damageInc = 4, }, + [4] = { spell_damageInc = 6, }, + [5] = { spell_damageInc = 8, }, + [6] = { spell_damageInc = 10, }, + [7] = { spell_damageInc = 12, }, + [8] = { spell_damageInc = 14, }, + [9] = { spell_damageInc = 16, }, + [10] = { spell_damageInc = 18, }, + [11] = { spell_damageInc = 20, }, + [12] = { spell_damageInc = 22, }, + [13] = { spell_damageInc = 24, }, + [14] = { spell_damageInc = 26, }, + [15] = { spell_damageInc = 28, }, + [16] = { spell_damageInc = 30, }, + [17] = { spell_damageInc = 32, }, + [18] = { spell_damageInc = 34, }, + [19] = { spell_damageInc = 36, }, + [20] = { spell_damageInc = 38, }, + [21] = { spell_damageInc = 40, }, + [22] = { spell_damageInc = 42, }, + [23] = { spell_damageInc = 44, }, + [24] = { spell_damageInc = 46, }, + [25] = { spell_damageInc = 48, }, + [26] = { spell_damageInc = 50, }, + [27] = { spell_damageInc = 52, }, + [28] = { spell_damageInc = 54, }, + [29] = { spell_damageInc = 56, }, + [30] = { spell_damageInc = 58, }, + } +} +gems["Item Quantity"] = { + support = true, + base = { + }, + quality = { + lootQuantityInc = 0.35 + }, + levels = { + [1] = { lootQuantityInc = 17, }, + [2] = { lootQuantityInc = 18, }, + [3] = { lootQuantityInc = 19, }, + [4] = { lootQuantityInc = 20, }, + [5] = { lootQuantityInc = 21, }, + [6] = { lootQuantityInc = 22, }, + [7] = { lootQuantityInc = 23, }, + [8] = { lootQuantityInc = 24, }, + [9] = { lootQuantityInc = 25, }, + [10] = { lootQuantityInc = 26, }, + [11] = { lootQuantityInc = 27, }, + [12] = { lootQuantityInc = 28, }, + [13] = { lootQuantityInc = 29, }, + [14] = { lootQuantityInc = 30, }, + [15] = { lootQuantityInc = 31, }, + [16] = { lootQuantityInc = 32, }, + [17] = { lootQuantityInc = 33, }, + [18] = { lootQuantityInc = 34, }, + [19] = { lootQuantityInc = 35, }, + [20] = { lootQuantityInc = 36, }, + [21] = { lootQuantityInc = 37, }, + [22] = { lootQuantityInc = 38, }, + [23] = { lootQuantityInc = 39, }, + [24] = { lootQuantityInc = 40, }, + [25] = { lootQuantityInc = 41, }, + [26] = { lootQuantityInc = 42, }, + [27] = { lootQuantityInc = 43, }, + [28] = { lootQuantityInc = 44, }, + [29] = { lootQuantityInc = 45, }, + [30] = { lootQuantityInc = 46, }, + } +} +gems["Knockback"] = { + unsupported = true, +} +gems["Less Duration"] = { + support = true, + base = { + manaCostMore = 1.2, + }, + quality = { + durationInc = -0.5, + }, + levels = { + [1] = { durationMore = 0.6, damageMore = 1.2, }, + [2] = { durationMore = 0.6, damageMore = 1.2, }, + [3] = { durationMore = 0.59, damageMore = 1.21, }, + [4] = { durationMore = 0.59, damageMore = 1.21, }, + [5] = { durationMore = 0.58, damageMore = 1.22, }, + [6] = { durationMore = 0.58, damageMore = 1.22, }, + [7] = { durationMore = 0.57, damageMore = 1.23, }, + [8] = { durationMore = 0.57, damageMore = 1.23, }, + [9] = { durationMore = 0.56, damageMore = 1.24, }, + [10] = { durationMore = 0.56, damageMore = 1.24, }, + [11] = { durationMore = 0.55, damageMore = 1.25, }, + [12] = { durationMore = 0.55, damageMore = 1.25, }, + [13] = { durationMore = 0.54, damageMore = 1.26, }, + [14] = { durationMore = 0.54, damageMore = 1.26, }, + [15] = { durationMore = 0.53, damageMore = 1.27, }, + [16] = { durationMore = 0.53, damageMore = 1.27, }, + [17] = { durationMore = 0.52, damageMore = 1.28, }, + [18] = { durationMore = 0.52, damageMore = 1.28, }, + [19] = { durationMore = 0.51, damageMore = 1.29, }, + [20] = { durationMore = 0.51, damageMore = 1.29, }, + [21] = { durationMore = 0.5, damageMore = 1.3, }, + [22] = { durationMore = 0.5, damageMore = 1.3, }, + [23] = { durationMore = 0.49, damageMore = 1.31, }, + [24] = { durationMore = 0.49, damageMore = 1.31, }, + [25] = { durationMore = 0.48, damageMore = 1.32, }, + [26] = { durationMore = 0.48, damageMore = 1.32, }, + [27] = { durationMore = 0.47, damageMore = 1.33, }, + [28] = { durationMore = 0.47, damageMore = 1.33, }, + [29] = { durationMore = 0.46, damageMore = 1.34, }, + [30] = { durationMore = 0.46, damageMore = 1.34, }, + } +} +gems["Life Gain on Hit"] = { + support = true, + attack = true, + base = { + manaCostMore = 1.5, + }, + quality = { + attack_lifeOnHitBase = 0.5, + }, + levels = { + [1] = { attack_lifeOnHitBase = 6, }, + [2] = { attack_lifeOnHitBase = 8, }, + [3] = { attack_lifeOnHitBase = 10, }, + [4] = { attack_lifeOnHitBase = 12, }, + [5] = { attack_lifeOnHitBase = 14, }, + [6] = { attack_lifeOnHitBase = 16, }, + [7] = { attack_lifeOnHitBase = 18, }, + [8] = { attack_lifeOnHitBase = 20, }, + [9] = { attack_lifeOnHitBase = 22, }, + [10] = { attack_lifeOnHitBase = 24, }, + [11] = { attack_lifeOnHitBase = 26, }, + [12] = { attack_lifeOnHitBase = 28, }, + [13] = { attack_lifeOnHitBase = 30, }, + [14] = { attack_lifeOnHitBase = 32, }, + [15] = { attack_lifeOnHitBase = 34, }, + [16] = { attack_lifeOnHitBase = 36, }, + [17] = { attack_lifeOnHitBase = 38, }, + [18] = { attack_lifeOnHitBase = 40, }, + [19] = { attack_lifeOnHitBase = 42, }, + [20] = { attack_lifeOnHitBase = 44, }, + [21] = { attack_lifeOnHitBase = 46, }, + [22] = { attack_lifeOnHitBase = 48, }, + [23] = { attack_lifeOnHitBase = 50, }, + [24] = { attack_lifeOnHitBase = 52, }, + [25] = { attack_lifeOnHitBase = 54, }, + [26] = { attack_lifeOnHitBase = 56, }, + [27] = { attack_lifeOnHitBase = 58, }, + [28] = { attack_lifeOnHitBase = 60, }, + [29] = { attack_lifeOnHitBase = 62, }, + [30] = { attack_lifeOnHitBase = 64, }, + } +} +gems["Life Leech"] = { + support = true, + base = { + manaCostMore = 1.3, + }, + quality = { + }, + levels = { + [1] = { }, + [2] = { }, + [3] = { }, + [4] = { }, + [5] = { }, + [6] = { }, + [7] = { }, + [8] = { }, + [9] = { }, + [10] = { }, + [11] = { }, + [12] = { }, + [13] = { }, + [14] = { }, + [15] = { }, + [16] = { }, + [17] = { }, + [18] = { }, + [19] = { }, + [20] = { }, + [21] = { }, + [22] = { }, + [23] = { }, + [24] = { }, + [25] = { }, + [26] = { }, + [27] = { }, + [28] = { }, + [29] = { }, + [30] = { }, + } +} +gems["Melee Damage on Full Life"] = { + support = true, + melee = true, + base = { + manaCostMore = 1.3, + }, + quality = { + melee_physicalInc = 0.5, + }, + levels = { + [1] = { condMod_FullLife_melee_physicalMore = 1.3, }, + [2] = { condMod_FullLife_melee_physicalMore = 1.31, }, + [3] = { condMod_FullLife_melee_physicalMore = 1.32, }, + [4] = { condMod_FullLife_melee_physicalMore = 1.33, }, + [5] = { condMod_FullLife_melee_physicalMore = 1.34, }, + [6] = { condMod_FullLife_melee_physicalMore = 1.35, }, + [7] = { condMod_FullLife_melee_physicalMore = 1.36, }, + [8] = { condMod_FullLife_melee_physicalMore = 1.37, }, + [9] = { condMod_FullLife_melee_physicalMore = 1.38, }, + [10] = { condMod_FullLife_melee_physicalMore = 1.39, }, + [11] = { condMod_FullLife_melee_physicalMore = 1.4, }, + [12] = { condMod_FullLife_melee_physicalMore = 1.41, }, + [13] = { condMod_FullLife_melee_physicalMore = 1.42, }, + [14] = { condMod_FullLife_melee_physicalMore = 1.43, }, + [15] = { condMod_FullLife_melee_physicalMore = 1.44, }, + [16] = { condMod_FullLife_melee_physicalMore = 1.45, }, + [17] = { condMod_FullLife_melee_physicalMore = 1.46, }, + [18] = { condMod_FullLife_melee_physicalMore = 1.47, }, + [19] = { condMod_FullLife_melee_physicalMore = 1.48, }, + [20] = { condMod_FullLife_melee_physicalMore = 1.49, }, + [21] = { condMod_FullLife_melee_physicalMore = 1.5, }, + [22] = { condMod_FullLife_melee_physicalMore = 1.51, }, + [23] = { condMod_FullLife_melee_physicalMore = 1.52, }, + [24] = { condMod_FullLife_melee_physicalMore = 1.53, }, + [25] = { condMod_FullLife_melee_physicalMore = 1.54, }, + [26] = { condMod_FullLife_melee_physicalMore = 1.55, }, + [27] = { condMod_FullLife_melee_physicalMore = 1.56, }, + [28] = { condMod_FullLife_melee_physicalMore = 1.57, }, + [29] = { condMod_FullLife_melee_physicalMore = 1.58, }, + [30] = { condMod_FullLife_melee_physicalMore = 1.59, }, + } +} +gems["Melee Physical Damage"] = { + support = true, + melee = true, + base = { + manaCostMore = 1.4, + }, + quality = { + melee_physicalInc = 0.5, + }, + levels = { + [1] = { melee_physicalMore = 1.3, }, + [2] = { melee_physicalMore = 1.31, }, + [3] = { melee_physicalMore = 1.32, }, + [4] = { melee_physicalMore = 1.33, }, + [5] = { melee_physicalMore = 1.34, }, + [6] = { melee_physicalMore = 1.35, }, + [7] = { melee_physicalMore = 1.36, }, + [8] = { melee_physicalMore = 1.37, }, + [9] = { melee_physicalMore = 1.38, }, + [10] = { melee_physicalMore = 1.39, }, + [11] = { melee_physicalMore = 1.4, }, + [12] = { melee_physicalMore = 1.41, }, + [13] = { melee_physicalMore = 1.42, }, + [14] = { melee_physicalMore = 1.43, }, + [15] = { melee_physicalMore = 1.44, }, + [16] = { melee_physicalMore = 1.45, }, + [17] = { melee_physicalMore = 1.46, }, + [18] = { melee_physicalMore = 1.47, }, + [19] = { melee_physicalMore = 1.48, }, + [20] = { melee_physicalMore = 1.49, }, + [21] = { melee_physicalMore = 1.5, }, + [22] = { melee_physicalMore = 1.51, }, + [23] = { melee_physicalMore = 1.52, }, + [24] = { melee_physicalMore = 1.53, }, + [25] = { melee_physicalMore = 1.54, }, + [26] = { melee_physicalMore = 1.55, }, + [27] = { melee_physicalMore = 1.56, }, + [28] = { melee_physicalMore = 1.57, }, + [29] = { melee_physicalMore = 1.58, }, + [30] = { melee_physicalMore = 1.59, }, + } +} +gems["Melee Splash"] = { + support = true, + attack = true, + melee = true, + base = { + manaCostMore = 1.6, + }, + quality = { + aoeRadiusInc = 0.5, + }, + levels = { + [1] = { aoeRadiusMore = 1, }, + [2] = { aoeRadiusMore = 1.01, }, + [3] = { aoeRadiusMore = 1.02, }, + [4] = { aoeRadiusMore = 1.03, }, + [5] = { aoeRadiusMore = 1.04, }, + [6] = { aoeRadiusMore = 1.05, }, + [7] = { aoeRadiusMore = 1.06, }, + [8] = { aoeRadiusMore = 1.07, }, + [9] = { aoeRadiusMore = 1.08, }, + [10] = { aoeRadiusMore = 1.09, }, + [11] = { aoeRadiusMore = 1.1, }, + [12] = { aoeRadiusMore = 1.11, }, + [13] = { aoeRadiusMore = 1.12, }, + [14] = { aoeRadiusMore = 1.13, }, + [15] = { aoeRadiusMore = 1.14, }, + [16] = { aoeRadiusMore = 1.15, }, + [17] = { aoeRadiusMore = 1.16, }, + [18] = { aoeRadiusMore = 1.17, }, + [19] = { aoeRadiusMore = 1.18, }, + [20] = { aoeRadiusMore = 1.19, }, + [21] = { aoeRadiusMore = 1.2, }, + [22] = { aoeRadiusMore = 1.21, }, + [23] = { aoeRadiusMore = 1.22, }, + [24] = { aoeRadiusMore = 1.23, }, + [25] = { aoeRadiusMore = 1.24, }, + [26] = { aoeRadiusMore = 1.25, }, + [27] = { aoeRadiusMore = 1.26, }, + [28] = { aoeRadiusMore = 1.27, }, + [29] = { aoeRadiusMore = 1.28, }, + [30] = { aoeRadiusMore = 1.29, }, + } +} +gems["Multistrike"] = { + support = true, + attack = true, + melee = true, + base = { + manaCostMore = 1.8, + attack_damageMore = 0.7, + }, + quality = { + melee_physicalInc = 0.5, + }, + levels = { + [1] = { attackSpeedMore = 1.75, }, + [2] = { attackSpeedMore = 1.76, }, + [3] = { attackSpeedMore = 1.77, }, + [4] = { attackSpeedMore = 1.78, }, + [5] = { attackSpeedMore = 1.79, }, + [6] = { attackSpeedMore = 1.8, }, + [7] = { attackSpeedMore = 1.81, }, + [8] = { attackSpeedMore = 1.82, }, + [9] = { attackSpeedMore = 1.83, }, + [10] = { attackSpeedMore = 1.84, }, + [11] = { attackSpeedMore = 1.85, }, + [12] = { attackSpeedMore = 1.86, }, + [13] = { attackSpeedMore = 1.87, }, + [14] = { attackSpeedMore = 1.88, }, + [15] = { attackSpeedMore = 1.89, }, + [16] = { attackSpeedMore = 1.9, }, + [17] = { attackSpeedMore = 1.91, }, + [18] = { attackSpeedMore = 1.92, }, + [19] = { attackSpeedMore = 1.93, }, + [20] = { attackSpeedMore = 1.94, }, + [21] = { attackSpeedMore = 1.95, }, + [22] = { attackSpeedMore = 1.96, }, + [23] = { attackSpeedMore = 1.97, }, + [24] = { attackSpeedMore = 1.98, }, + [25] = { attackSpeedMore = 1.99, }, + [26] = { attackSpeedMore = 2, }, + [27] = { attackSpeedMore = 2.01, }, + [28] = { attackSpeedMore = 2.02, }, + [29] = { attackSpeedMore = 2.03, }, + [30] = { attackSpeedMore = 2.04, }, + } +} +gems["Ranged Attack Totem"] = { + support = true, + totem = true, + projectile = true, + addFlags = { + totem = true, + }, + base = { + manaCostMore = 2, + attackSpeedMore = 0.7, + }, + quality = { + totemPlacementSpeedInc = 1, + }, + levels = { + [1] = { attack_damageMore = 0.5, }, + [2] = { attack_damageMore = 0.51, }, + [3] = { attack_damageMore = 0.52, }, + [4] = { attack_damageMore = 0.53, }, + [5] = { attack_damageMore = 0.54, }, + [6] = { attack_damageMore = 0.55, }, + [7] = { attack_damageMore = 0.56, }, + [8] = { attack_damageMore = 0.57, }, + [9] = { attack_damageMore = 0.58, }, + [10] = { attack_damageMore = 0.59, }, + [11] = { attack_damageMore = 0.6, }, + [12] = { attack_damageMore = 0.61, }, + [13] = { attack_damageMore = 0.62, }, + [14] = { attack_damageMore = 0.63, }, + [15] = { attack_damageMore = 0.64, }, + [16] = { attack_damageMore = 0.65, }, + [17] = { attack_damageMore = 0.66, }, + [18] = { attack_damageMore = 0.67, }, + [19] = { attack_damageMore = 0.68, }, + [20] = { attack_damageMore = 0.69, }, + [21] = { attack_damageMore = 0.7, }, + [22] = { attack_damageMore = 0.71, }, + [23] = { attack_damageMore = 0.72, }, + [24] = { attack_damageMore = 0.73, }, + [25] = { attack_damageMore = 0.74, }, + [26] = { attack_damageMore = 0.75, }, + [27] = { attack_damageMore = 0.76, }, + [28] = { attack_damageMore = 0.77, }, + [29] = { attack_damageMore = 0.78, }, + [30] = { attack_damageMore = 0.79, }, + } +} +gems["Reduced Mana"] = { + support = true, + base = { + }, + quality = { + skill_costInc = -0.25, + }, + levels = { + [1] = { skill_costInc = -25, }, + [2] = { skill_costInc = -25, }, + [3] = { skill_costInc = -26, }, + [4] = { skill_costInc = -26, }, + [5] = { skill_costInc = -27, }, + [6] = { skill_costInc = -27, }, + [7] = { skill_costInc = -28, }, + [8] = { skill_costInc = -28, }, + [9] = { skill_costInc = -29, }, + [10] = { skill_costInc = -29, }, + [11] = { skill_costInc = -30, }, + [12] = { skill_costInc = -30, }, + [13] = { skill_costInc = -31, }, + [14] = { skill_costInc = -31, }, + [15] = { skill_costInc = -32, }, + [16] = { skill_costInc = -32, }, + [17] = { skill_costInc = -33, }, + [18] = { skill_costInc = -33, }, + [19] = { skill_costInc = -34, }, + [20] = { skill_costInc = -34, }, + [21] = { skill_costInc = -35, }, + [22] = { skill_costInc = -35, }, + [23] = { skill_costInc = -36, }, + [24] = { skill_costInc = -36, }, + [25] = { skill_costInc = -37, }, + [26] = { skill_costInc = -37, }, + [27] = { skill_costInc = -38, }, + [28] = { skill_costInc = -38, }, + [29] = { skill_costInc = -39, }, + [30] = { skill_costInc = -39, }, + } +} +gems["Spell Totem"] = { + support = true, + totem = true, + addFlags = { + totem = true, + }, + base = { + manaCostMore = 2, + castSpeedMore = 0.7, + }, + quality = { + totemPlacementSpeedInc = 1, + }, + levels = { + [1] = { spell_damageMore = 0.5, }, + [2] = { spell_damageMore = 0.51, }, + [3] = { spell_damageMore = 0.52, }, + [4] = { spell_damageMore = 0.53, }, + [5] = { spell_damageMore = 0.54, }, + [6] = { spell_damageMore = 0.55, }, + [7] = { spell_damageMore = 0.56, }, + [8] = { spell_damageMore = 0.57, }, + [9] = { spell_damageMore = 0.58, }, + [10] = { spell_damageMore = 0.59, }, + [11] = { spell_damageMore = 0.6, }, + [12] = { spell_damageMore = 0.61, }, + [13] = { spell_damageMore = 0.62, }, + [14] = { spell_damageMore = 0.63, }, + [15] = { spell_damageMore = 0.64, }, + [16] = { spell_damageMore = 0.65, }, + [17] = { spell_damageMore = 0.66, }, + [18] = { spell_damageMore = 0.67, }, + [19] = { spell_damageMore = 0.68, }, + [20] = { spell_damageMore = 0.69, }, + [21] = { spell_damageMore = 0.7, }, + [22] = { spell_damageMore = 0.71, }, + [23] = { spell_damageMore = 0.72, }, + [24] = { spell_damageMore = 0.73, }, + [25] = { spell_damageMore = 0.74, }, + [26] = { spell_damageMore = 0.75, }, + [27] = { spell_damageMore = 0.76, }, + [28] = { spell_damageMore = 0.77, }, + [29] = { spell_damageMore = 0.78, }, + [30] = { spell_damageMore = 0.79, }, + } +} +gems["Stun"] = { + support = true, + base = { + }, + quality = { + stunEnemyDurInc = 1.5, + }, + levels = { + [1] = { stunEnemyThreshInc = -30, }, + [2] = { stunEnemyThreshInc = -31, }, + [3] = { stunEnemyThreshInc = -32, }, + [4] = { stunEnemyThreshInc = -33, }, + [5] = { stunEnemyThreshInc = -34, }, + [6] = { stunEnemyThreshInc = -35, }, + [7] = { stunEnemyThreshInc = -36, }, + [8] = { stunEnemyThreshInc = -37, }, + [9] = { stunEnemyThreshInc = -38, }, + [10] = { stunEnemyThreshInc = -39, }, + [11] = { stunEnemyThreshInc = -40, }, + [12] = { stunEnemyThreshInc = -41, }, + [13] = { stunEnemyThreshInc = -42, }, + [14] = { stunEnemyThreshInc = -43, }, + [15] = { stunEnemyThreshInc = -44, }, + [16] = { stunEnemyThreshInc = -45, }, + [17] = { stunEnemyThreshInc = -46, }, + [18] = { stunEnemyThreshInc = -47, }, + [19] = { stunEnemyThreshInc = -48, }, + [20] = { stunEnemyThreshInc = -49, }, + [21] = { stunEnemyThreshInc = -50, }, + [22] = { stunEnemyThreshInc = -51, }, + [23] = { stunEnemyThreshInc = -52, }, + [24] = { stunEnemyThreshInc = -53, }, + [25] = { stunEnemyThreshInc = -54, }, + [26] = { stunEnemyThreshInc = -55, }, + [27] = { stunEnemyThreshInc = -56, }, + [28] = { stunEnemyThreshInc = -57, }, + [29] = { stunEnemyThreshInc = -58, }, + [30] = { stunEnemyThreshInc = -59, }, + } +} +gems["Weapon Elemental Damage"] = { + support = true, + attack = true, + base = { + manaCostMore = 1.4, + }, + quality = { + weapon_elemInc = 0.5, + }, + levels = { + [1] = { weapon_elemMore = 1.4, }, + [2] = { weapon_elemMore = 1.41, }, + [3] = { weapon_elemMore = 1.42, }, + [4] = { weapon_elemMore = 1.43, }, + [5] = { weapon_elemMore = 1.44, }, + [6] = { weapon_elemMore = 1.45, }, + [7] = { weapon_elemMore = 1.46, }, + [8] = { weapon_elemMore = 1.47, }, + [9] = { weapon_elemMore = 1.48, }, + [10] = { weapon_elemMore = 1.49, }, + [11] = { weapon_elemMore = 1.5, }, + [12] = { weapon_elemMore = 1.51, }, + [13] = { weapon_elemMore = 1.52, }, + [14] = { weapon_elemMore = 1.53, }, + [15] = { weapon_elemMore = 1.54, }, + [16] = { weapon_elemMore = 1.55, }, + [17] = { weapon_elemMore = 1.56, }, + [18] = { weapon_elemMore = 1.57, }, + [19] = { weapon_elemMore = 1.58, }, + [20] = { weapon_elemMore = 1.59, }, + [21] = { weapon_elemMore = 1.6, }, + [22] = { weapon_elemMore = 1.61, }, + [23] = { weapon_elemMore = 1.62, }, + [24] = { weapon_elemMore = 1.63, }, + [25] = { weapon_elemMore = 1.64, }, + [26] = { weapon_elemMore = 1.65, }, + [27] = { weapon_elemMore = 1.66, }, + [28] = { weapon_elemMore = 1.67, }, + [29] = { weapon_elemMore = 1.68, }, + [30] = { weapon_elemMore = 1.69, }, + } +} \ No newline at end of file diff --git a/Items.lua b/Items.lua new file mode 100644 index 00000000..263447a7 --- /dev/null +++ b/Items.lua @@ -0,0 +1,533 @@ +local launch, cfg, main = ... + +local t_insert = table.insert +local m_floor = math.floor +local s_format = string.format + +local items = { } + +local function applyRange(line, range) + return line:gsub("%((%d+)%-(%d+) to (%d+)%-(%d+)%)", function(minMin, maxMin, minMax, maxMax) return string.format("%d-%d", tonumber(minMin) + range * (tonumber(minMax) - tonumber(minMin)), tonumber(maxMin) + range * (tonumber(maxMax) - tonumber(maxMin))) end) + :gsub("%((%d+) to (%d+)%)", function(min, max) return tostring(tonumber(min) + range * (tonumber(max) - tonumber(min))) end) +end + +items.slots = { } +items.controls = { } + +items.controls.addDisplayItem = common.newButton(0, 0, 60, 20, "Add", function() + items:AddDisplayItem() +end) + +local function mkItemSlot(x, y, slotName, slotLabel) + local slot = { } + slot.items = { } + slot.list = { } + slot.x = x + slot.y = y + slot.width = 320 + slot.height = 20 + slot.slotName = slotName + slot.label = slotLabel or slotName + slot.dropDown = common.newDropDown(x, y, slot.width, slot.height, slot.list, function(sel) + if slot.items[sel] ~= slot.selItem then + slot.selItem = slot.items[sel] + items:PopulateSlots() + items.buildFlag = true + items.modFlag = true + end + end) + function slot:Populate() + wipeTable(self.items) + wipeTable(self.list) + self.items[1] = 0 + self.list[1] = "None" + self.dropDown.sel = 1 + for _, item in ipairs(items.list) do + if items:IsItemValidForSlot(item, slotName) then + t_insert(self.items, item.id) + t_insert(self.list, data.colorCodes[item.rarity]..item.name) + if item.id == self.selItem then + self.dropDown.sel = #self.list + end + end + end + if not self.selItem or not items.list[self.selItem] or not items:IsItemValidForSlot(items.list[self.selItem], slotName) then + self.selItem = 0 + end + end + function slot:Draw(viewPort) + self.dropDown.x = viewPort.x + self.x + self.dropDown.y = viewPort.y + self.y + DrawString(self.dropDown.x - 2, self.dropDown.y + 2, "RIGHT_X", self.height - 4, "VAR", "^7"..slot.label..":") + self.dropDown:Draw() + if self.dropDown:IsMouseOver() then + local ttItem + if self.dropDown.dropped then + if self.dropDown.hoverSel then + ttItem = items.list[self.items[self.dropDown.hoverSel]] + end + elseif self.selItem and not items.selControl then + ttItem = items.list[self.selItem] + end + if ttItem then + items:AddItemTooltip(ttItem) + main:DrawTooltip(self.dropDown.x, self.dropDown.y, self.width, self.height, viewPort, data.colorCodes[ttItem.rarity], true) + end + end + end + function slot:IsMouseOver() + return self.dropDown:IsMouseOver() + end + function slot:OnKeyDown(key) + return self.dropDown:OnKeyDown(key) + end + function slot:OnKeyUp(key) + return self.dropDown:OnKeyUp(key) + end + items.slots[slotName] = slot + return slot +end + +local baseSlots = { "Helmet", "Body Armour", "Gloves", "Boots", "Amulet", "Ring 1", "Ring 2", "Belt", "Weapon 1", "Weapon 2" } +for index, slotName in pairs(baseSlots) do + t_insert(items.controls, mkItemSlot(400, (index - 1) * 20, slotName)) +end + +function items:IsItemValidForSlot(item, slotName) + if item.type == slotName:gsub(" %d+","") then + return true + elseif slotName == "Weapon 1" or slotName == "Weapon" then + return data.itemBases[item.baseName].weapon ~= nil + elseif slotName == "Weapon 2" then + local weapon1Sel = self.slots["Weapon 1"].selItem + local weapon1Type = weapon1Sel > 0 and data.itemBases[self.list[weapon1Sel].baseName].type or "None" + if weapon1Type == "Bow" then + return item.type == "Quiver" + elseif data.weaponTypeInfo[weapon1Type].oneHand then + return item.type == "Shield" or (data.weaponTypeInfo[item.type] and data.weaponTypeInfo[item.type].oneHand and (weapon1Type == "None" or (weapon1Type == "Wand" and item.type == "Wand") or (weapon1Type ~= "Wand" and item.type ~= "Wand"))) + end + end +end + +function items:PopulateSlots() + for _, slot in pairs(self.slots) do + slot:Populate() + end +end + +function items:UpdateJewels() + local spec = self.build.spec + for nodeId, slot in pairs(self.sockets) do + if not spec.allocNodes[nodeId] then + slot.inactive = true + self.controls["socket"..nodeId] = nil + end + end + local socketList = { } + for nodeId, node in pairs(spec.allocNodes) do + if node.type == "socket" then + t_insert(socketList, nodeId) + end + end + table.sort(socketList) + for index, nodeId in pairs(socketList) do + local slot = self.sockets[nodeId] + self.controls["socket"..nodeId] = slot + slot.inactive = false + slot.y = (#baseSlots + index - 1) * 20 + end +end + +function items:GetSocketJewel(nodeId) + return self.sockets[nodeId], self.list[self.sockets[nodeId].selItem] +end + +function items:ParseItemRaw(item) + if not item.id then + item.id = 1 + while self.list[item.id] do + item.id = item.id + 1 + end + end + item.name = "?" + item.rarity = "UNIQUE" + item.rawLines = { } + for line in string.gmatch(item.raw .. "\r\n", "([^\r\n]*)\r?\n") do + line = line:gsub("^%s+",""):gsub("%s+$","") + if #line > 0 then + t_insert(item.rawLines, line) + end + end + local mode = "WIKI" + local l = 1 + if item.rawLines[l] then + local rarity = item.rawLines[l]:match("^Rarity: (%a+)") + if rarity then + mode = "GAME" + item.rarity = rarity:upper() + l = l + 1 + end + end + if item.rawLines[l] then + item.name = item.rawLines[l] + l = l + 1 + end + if item.rarity == "NORMAL" or item.rarity == "MAGIC" then + for baseName, baseData in pairs(data.itemBases) do + if item.name:find(baseName, 1, true) then + item.baseName = baseName + item.type = baseData.type + break + end + end + elseif item.rawLines[l] and not item.rawLines[l]:match("^%-") and data.itemBases[item.rawLines[l]] then + item.baseName = item.rawLines[l] + item.title = item.name + item.name = item.title .. ", " .. item.baseName + item.type = data.itemBases[item.baseName].type + end + item.modLines = { } + while item.rawLines[l] do + local line = item.rawLines[l] + if data.weaponTypeInfo[line] then + item.weaponType = line + else + local specName, specVal = line:match("^([%a ]+): %+?([%d%-%.]+)") + if not specName then + specName, specVal = line:match("^([%a ]+): (.+)") + end + if specName then + if specName == "Radius" and item.type == "Jewel" then + for index, data in pairs(data.jewelRadius) do + if specVal == data.label then + item.radius = index + break + end + end + end + else + local rangedLine + if line:match("%(%d+%-%d+ to %d+%-%d+%)") or line:match("%(%d+ to %d+%)") then + rangedLine = applyRange(line, 1) + end + local modList, extra = mod.parseMod(rangedLine or line) + if modList then + t_insert(item.modLines, { line = line, extra = extra, mods = modList, range = rangedLine and 1 }) + end + end + end + l = l + 1 + end + self:BuildItemModList(item) +end + +function items:BuildItemModList(item) + local modList = { } + item.modList = modList + for _, modLine in ipairs(item.modLines) do + if not modLine.extra then + if modLine.range then + local line = applyRange(modLine.line, modLine.range) + local list, extra = mod.parseMod(line) + if list and not extra then + mod.mods = list + end + end + for k, v in pairs(modLine.mods) do + mod.listMerge(modList, k, v) + end + end + end + local base = data.itemBases[item.baseName] + if not base then + return + end + if base.weapon then + modList.weaponX_type = base.type + modList.weaponX_name = item.name + for _, elem in pairs({"physical","lightning","cold","fire","chaos"}) do + local min = (base.weapon[elem.."Min"] or 0) + (modList["attack_"..elem.."Min"] or 0) + local max = (base.weapon[elem.."Max"] or 0) + (modList["attack_"..elem.."Max"] or 0) + if elem == "physical" then + if modList.weaponNoPhysical then + min, max = 0, 0 + else + min = m_floor(min * (1 + (modList["physicalInc"] or 0) / 100 + .2) + 0.5) + max = m_floor(max * (1 + (modList["physicalInc"] or 0) / 100 + .2) + 0.5) + end + modList["physicalInc"] = nil + end + if min > 0 and max > 0 then + modList["weaponX_"..elem.."Min"] = min + modList["weaponX_"..elem.."Max"] = max + end + modList["attack_"..elem.."Min"] = nil + modList["attack_"..elem.."Max"] = nil + end + modList.weaponX_attackRate = m_floor(base.weapon.attackRateBase * (1 + (modList.attackSpeedInc or 0) / 100) * 100 + 0.5) / 100 + modList.attackSpeedInc = nil + if modList.weaponAlwaysCrit then + modList.weaponX_critChanceBase = 100 + else + modList.weaponX_critChanceBase = m_floor(base.weapon.critChanceBase * (1 + (modList.critChanceInc or 0) / 100) * 100 + 0.5) / 100 + end + modList.critChanceInc = nil + elseif base.armour then + if base.type == "Shield" then + modList.weaponX_type = "Shield" + end + if base.armour.armourBase then + modList.armourBase = m_floor((base.armour.armourBase + (modList.armourBase or 0)) * (1 + ((modList.armourInc or 0) + (modList.armourAndEvasionInc or 0) + (modList.armourAndESInc or 0) + 20) / 100) + 0.5) + end + if base.armour.evasionBase then + modList.evasionBase = m_floor((base.armour.evasionBase + (modList.evasionBase or 0)) * (1 + ((modList.evasionInc or 0) + (modList.armourAndEvasionInc or 0) + (modList.evasionAndEnergyShieldInc or 0) + 20) / 100) + 0.5) + end + if base.armour.energyShieldBase then + modList.energyShieldBase = m_floor((base.armour.energyShieldBase + (modList.energyShieldBase or 0)) * (1 + ((modList.energyShieldInc or 0) + (modList.armourAndEnergyShieldInc or 0) + (modList.evasionAndEnergyShieldInc or 0) + 20) / 100) + 0.5) + end + if base.armour.blockChance then + if modList.shieldNoBlock then + modList.blockChance = 0 + else + modList.blockChance = base.armour.blockChance + (modList.blockChance or 0) + end + end + modList.armourInc = nil + modList.evasionInc = nil + modList.energyShieldInc = nil + modList.armourAndEvasionInc = nil + modList.armourAndESInc = nil + modList.evasionAndEnergyShieldInc = nil + elseif item.type == "Jewel" then + item.jewelFunc = modList.jewelFunc + modList.jewelFunc = nil + end +end + +function items:AddItemTooltip(item) + local rarityCode = data.colorCodes[item.rarity] + if item.title then + main:AddTooltipLine(20, rarityCode..item.title) + main:AddTooltipLine(20, rarityCode..item.baseName) + else + main:AddTooltipLine(20, rarityCode..item.name) + end + local base = data.itemBases[item.baseName] + modList = item.modList + if base.weapon then + main:AddTooltipSeperator(10) + main:AddTooltipLine(16, s_format("^x7F7F7F%s", base.type)) + main:AddTooltipLine(16, "^x7F7F7FQuality: "..data.colorCodes.MAGIC.."+20%") + if modList.weaponX_physicalMin then + main:AddTooltipLine(16, s_format("^x7F7F7FPhysical Damage: "..data.colorCodes.MAGIC.."%d-%d", modList.weaponX_physicalMin, modList.weaponX_physicalMax)) + end + local elemLine + for _, var in ipairs({"fire","cold","lightning"}) do + if modList["weaponX_"..var.."Min"] then + elemLine = elemLine and elemLine.."^x7F7F7F, " or "^x7F7F7FElemental Damage: " + elemLine = elemLine..s_format("%s%d-%d", data.colorCodes[var:upper()], modList["weaponX_"..var.."Min"], modList["weaponX_"..var.."Max"]) + end + end + if elemLine then + main:AddTooltipLine(16, elemLine) + end + if modList.weaponX_chaosMin then + main:AddTooltipLine(16, s_format("^x7F7F7FChaos Damage: "..data.colorCodes.CHAOS.."%d-%d", modList.weaponX_chaosMin, modList.weaponX_chaosMax)) + end + main:AddTooltipLine(16, s_format("^x7F7F7FCritical Strike Chance: %s%.2f%%", modList.weaponX_critChanceBase ~= base.weapon.critChanceBase and data.colorCodes.MAGIC or "^7", modList.weaponX_critChanceBase)) + main:AddTooltipLine(16, s_format("^x7F7F7FAttacks per Second: %s%.2f", modList.weaponX_attackRate ~= base.weapon.attackRateBase and data.colorCodes.MAGIC or "^7", modList.weaponX_attackRate)) + elseif base.armour then + main:AddTooltipSeperator(10) + main:AddTooltipLine(16, "^x7F7F7FQuality: "..data.colorCodes.MAGIC.."+20%") + if base.armour.blockChance and modList.blockChance > 0 then + main:AddTooltipLine(16, s_format("^x7F7F7FChance to Block: %s%d%%", modList.blockChance ~= base.armour.blockChance and data.colorCodes.MAGIC or "^7", modList.blockChance)) + end + for _, def in ipairs({{var="armour",label="Armour"},{var="evasion",label="Evasion Rating"},{var="energyShield",label="Energy Shield"}}) do + local itemVal = modList[def.var.."Base"] + if itemVal then + main:AddTooltipLine(16, s_format("^x7F7F7F%s: %s%d", def.label, itemVal ~= base.armour[def.var.."Base"] and data.colorCodes.MAGIC or "^7", itemVal)) + end + end + elseif item.radius then + main:AddTooltipSeperator(10) + main:AddTooltipLine(16, "^x7F7F7FRadius: ^7"..data.jewelRadius[item.radius].label) + end + if item.modLines[1] then + main:AddTooltipSeperator(10) + for index, modLine in pairs(item.modLines) do + local line = modLine.range and applyRange(modLine.line, modLine.range) or modLine.line + main:AddTooltipLine(16, (modLine.extra and data.colorCodes.NORMAL or data.colorCodes.MAGIC)..line) + if index == 1 and base.implicit and item.modLines[2] then + main:AddTooltipSeperator(10) + end + end + end + self:UpdateJewels() + for slotName, slot in pairs(self.slots) do + local selItem = self.list[slot.selItem] + if items:IsItemValidForSlot(item, slotName) and not slot.inactive and (item ~= selItem or item.type == "Jewel") then + local calcFunc, calcBase = self.build.calcs:GetItemCalculator() + if calcFunc then + local output = calcFunc(slotName, item ~= selItem and item) + local header = false + for _, statData in ipairs(self.build.displayStats) do + if statData.mod then + local diff = (output[statData.mod] or 0) - (calcBase[statData.mod] or 0) + if diff > 0.001 or diff < -0.001 then + if not header then + main:AddTooltipSeperator(14) + if item == selItem then + main:AddTooltipLine(14, "^7Removing this jewel will give you:") + else + main:AddTooltipLine(14, string.format("^7Equipping this item in %s%s will give you:", slot.label, selItem and " (replacing "..data.colorCodes[selItem.rarity]..selItem.name.."^7)" or "")) + end + header = true + end + main:AddTooltipLine(14, string.format("%s%+"..statData.fmt.." %s", diff > 0 and "^x00FF44" or "^xFF3300", diff * (statData.pc and 100 or 1), statData.label)) + end + end + end + end + end + end + if IsKeyDown("ALT") then + main:AddTooltipSeperator(10) + local nameList = { } + for k in pairs(modList) do + t_insert(nameList, k) + end + table.sort(nameList) + for _, name in ipairs(nameList) do + main:AddTooltipLine(16, "^7"..name.." = "..tostring(modList[name])) + end + end +end + +function items:AddDisplayItem() + for _, item in pairs(self.list) do + if item.raw == self.displayItem.raw then + self.displayItem = nil + return + end + end + if not self.list[self.displayItem.id] then + t_insert(self.orderList, self.displayItem.id) + end + self.list[self.displayItem.id] = self.displayItem + self.displayItem = nil + self:PopulateSlots() +end + +function items:Init(build) + self.build = build + self.list = { } + self.sockets = { } + for _, node in pairs(main.tree.nodes) do + if node.type == "socket" then + self.sockets[node.id] = mkItemSlot(400, 0, "Jewel "..node.id, "Socket") + end + end + self.orderList = { } +end +function items:Shutdown() + +end + +function items:Load(xml, dbFileName) + for _, node in ipairs(xml) do + if node.elem == "Item" then + local item = { } + item.raw = "" + item.id = tonumber(node.attrib.id) + self:ParseItemRaw(item) + for _, child in ipairs(node) do + if type(child) == "string" then + item.raw = child + self:ParseItemRaw(item) + elseif child.elem == "ModRange" then + local id = tonumber(child.attrib.id) or 0 + local range = tonumber(child.attrib.range) or 1 + if item.modLines[id] then + item.modLines[id].range = range + end + end + end + self:BuildItemModList(item) + self.list[item.id] = item + t_insert(self.orderList, item.id) + elseif node.elem == "Slot" then + if self.slots[node.attrib.name or ""] then + self.slots[node.attrib.name].selItem = tonumber(node.attrib.itemId) + end + end + end + self:PopulateSlots() +end +function items:Save(xml) + self.modFlag = false + for _, id in ipairs(self.orderList) do + local item = self.list[id] + local child = { elem = "Item", attrib = { id = tostring(id) } } + t_insert(child, item.raw) + for id, modLine in ipairs(item.modLines) do + if modLine.range then + t_insert(child, { elem = "ModRange", attrib = { id = tostring(id), range = tostring(modLine.range) } }) + end + end + t_insert(xml, child) + end + for name, slot in pairs(self.slots) do + t_insert(xml, { elem = "Slot", attrib = { name = name, itemId = tostring(slot.selItem) }}) + end +end + +function items:DrawItems(viewPort, inputEvents) + common.controlsInput(self, inputEvents) + for id, event in ipairs(inputEvents) do + if event.type == "KeyDown" then + if event.key == "v" and IsKeyDown("CTRL") then + local newItem = Paste() + if newItem then + self.displayItem = { + raw = newItem:gsub("^%s+",""):gsub("%s+$",""):gsub("–","-"):gsub("%b<>",""):gsub("ö","o") + } + self:ParseItemRaw(self.displayItem) + if not self.displayItem.baseName then + self.displayItem = nil + end + end + end + end + end + + if self.displayItem then + self.controls.addDisplayItem.x = viewPort.x + viewPort.width - 530 + self.controls.addDisplayItem.y = viewPort.y + 4 + self.controls.addDisplayItem.hidden = false + self.controls.addDisplayItem.label = self.list[self.displayItem.id] and "Save" or "Add" + self:AddItemTooltip(self.displayItem) + main:DrawTooltip(viewPort.x + viewPort.width - 500, viewPort.y + 28, nil, nil, viewPort, data.colorCodes[self.displayItem.rarity], true) + else + self.controls.addDisplayItem.hidden = true + end + + self:UpdateJewels() + + common.controlsDraw(self, viewPort) + + for index, id in pairs(self.orderList) do + local item = self.list[id] + local rarityCode = data.colorCodes[item.rarity] + SetDrawColor(rarityCode) + local x = viewPort.x + 2 + local y = viewPort.y + 2 + 16 * (index - 1) + DrawString(x, y, "LEFT", 16, "VAR", item.name) + local cx, cy = GetCursorPos() + if cx >= x and cx < x + 250 and cy >= y and cy < y + 16 then + self:AddItemTooltip(item) + main:DrawTooltip(x, y, 250, 16, viewPort, rarityCode, true) + end + end +end + +return items \ No newline at end of file diff --git a/Items/SourceStat3.lnk b/Items/SourceStat3.lnk new file mode 100644 index 00000000..642c7bd3 Binary files /dev/null and b/Items/SourceStat3.lnk differ diff --git a/Items/axe.lua b/Items/axe.lua new file mode 100644 index 00000000..5a0b83ba --- /dev/null +++ b/Items/axe.lua @@ -0,0 +1,245 @@ +local itemBases = ... + +itemBases["Rusted Hatchet"] = { + type = "One Handed Axe", + weapon = { physicalMin = 5, physicalMax = 9, critChanceBase = 5, attackRateBase = 1.5, }, + req = { }, +} +itemBases["Jade Hatchet"] = { + type = "One Handed Axe", + weapon = { physicalMin = 8, physicalMax = 13, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 6, str = 21, }, +} +itemBases["Boarding Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 9, physicalMax = 17, critChanceBase = 5, attackRateBase = 1.5, }, + req = { level = 11, str = 28, dex = 19, }, +} +itemBases["Cleaver"] = { + type = "One Handed Axe", + weapon = { physicalMin = 11, physicalMax = 33, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 16, str = 48, }, +} +itemBases["Broad Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 17, physicalMax = 31, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 21, str = 54, dex = 25, }, +} +itemBases["Arming Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 12, physicalMax = 36, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 25, str = 58, dex = 33, }, +} +itemBases["Decorative Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 23, physicalMax = 43, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 29, str = 80, dex = 23, }, +} +itemBases["Spectral Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 26, physicalMax = 43, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 33, str = 85, dex = 37, }, +} +itemBases["Etched Hatchet"] = { + type = "One Handed Axe", + implicit = "8% increased Physical Damage", + weapon = { physicalMin = 24, physicalMax = 42, critChanceBase = 5, attackRateBase = 1.35, }, + req = { level = 35, str = 93, dex = 43, }, +} +itemBases["Jasper Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 31, physicalMax = 47, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 36, str = 86, dex = 40, }, +} +itemBases["Tomahawk"] = { + type = "One Handed Axe", + weapon = { physicalMin = 25, physicalMax = 47, critChanceBase = 5, attackRateBase = 1.5, }, + req = { level = 39, str = 66, dex = 45, }, +} +itemBases["Wrist Chopper"] = { + type = "One Handed Axe", + weapon = { physicalMin = 23, physicalMax = 68, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 42, str = 112, dex = 32, }, +} +itemBases["War Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 30, physicalMax = 55, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 45, str = 106, dex = 49, }, +} +itemBases["Chest Splitter"] = { + type = "One Handed Axe", + weapon = { physicalMin = 20, physicalMax = 61, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 48, str = 105, dex = 60, }, +} +itemBases["Ceremonial Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 37, physicalMax = 69, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 51, str = 134, dex = 39, }, +} +itemBases["Wraith Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 39, physicalMax = 65, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 54, str = 134, dex = 59, }, +} +itemBases["Engraved Hatchet"] = { + type = "One Handed Axe", + implicit = "8% increased Physical Damage", + weapon = { physicalMin = 35, physicalMax = 63, critChanceBase = 5, attackRateBase = 1.35, }, + req = { level = 56, str = 143, dex = 66, }, +} +itemBases["Karui Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 41, physicalMax = 64, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 57, str = 132, dex = 62, }, +} +itemBases["Siege Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 32, physicalMax = 59, critChanceBase = 5, attackRateBase = 1.5, }, + req = { level = 59, str = 119, dex = 82, }, +} +itemBases["Reaver Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 31, physicalMax = 92, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 61, str = 167, dex = 57, }, +} +itemBases["Butcher Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 38, physicalMax = 71, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 63, str = 149, dex = 76, }, +} +itemBases["Vaal Hatchet"] = { + type = "One Handed Axe", + weapon = { physicalMin = 25, physicalMax = 74, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 65, str = 140, dex = 86, }, +} +itemBases["Royal Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 43, physicalMax = 80, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 67, str = 167, dex = 57, }, +} +itemBases["Infernal Axe"] = { + type = "One Handed Axe", + weapon = { physicalMin = 43, physicalMax = 72, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 69, str = 158, dex = 76, }, +} +itemBases["Runic Hatchet"] = { + type = "One Handed Axe", + implicit = "12% increased Physical Damage", + weapon = { physicalMin = 38, physicalMax = 68, critChanceBase = 5, attackRateBase = 1.35, }, + req = { level = 71, str = 163, dex = 82, }, +} + + +itemBases["Stone Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 10, physicalMax = 17, critChanceBase = 5, attackRateBase = 1.3, }, + req = { str = 17, }, +} +itemBases["Jade Chopper"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 17, physicalMax = 27, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 9, str = 31, }, +} +itemBases["Woodsplitter"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 17, physicalMax = 35, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 13, str = 36, dex = 17, }, +} +itemBases["Poleaxe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 29, physicalMax = 44, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 18, str = 44, dex = 25, }, +} +itemBases["Double Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 32, physicalMax = 54, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 23, str = 62, dex = 27, }, +} +itemBases["Gilded Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 43, physicalMax = 58, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 28, str = 64, dex = 37, }, +} +itemBases["Shadow Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 42, physicalMax = 62, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 33, str = 80, dex = 37, }, +} +itemBases["Jasper Chopper"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 50, physicalMax = 78, critChanceBase = 5, attackRateBase = 1.15, }, + req = { level = 37, str = 100, dex = 29, }, +} +itemBases["Dagger Axe"] = { + type = "Two Handed Axe", + implicit = "25% increased Critical Strike Chance", + weapon = { physicalMin = 45, physicalMax = 71, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 36, str = 89, dex = 43, }, +} +itemBases["Timber Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 41, physicalMax = 85, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 41, str = 97, dex = 45, }, +} +itemBases["Headsman Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 53, physicalMax = 79, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 45, str = 99, dex = 57, }, +} +itemBases["Labrys"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 71, physicalMax = 118, critChanceBase = 5, attackRateBase = 1.15, }, + req = { level = 49, str = 122, dex = 53, }, +} +itemBases["Noble Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 73, physicalMax = 98, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 52, str = 113, dex = 65, }, +} +itemBases["Abyssal Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 69, physicalMax = 104, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 55, str = 128, dex = 60, }, +} +itemBases["Talon Axe"] = { + type = "Two Handed Axe", + implicit = "25% increased Critical Strike Chance", + weapon = { physicalMin = 75, physicalMax = 118, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 59, str = 140, dex = 67, }, +} +itemBases["Karui Chopper"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 80, physicalMax = 125, critChanceBase = 5, attackRateBase = 1.15, }, + req = { level = 58, str = 151, dex = 43, }, +} +itemBases["Sundering Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 62, physicalMax = 128, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 60, str = 149, dex = 76, }, +} +itemBases["Ezomyte Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 72, physicalMax = 108, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 62, str = 140, dex = 86, }, +} +itemBases["Vaal Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 79, physicalMax = 131, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 64, str = 158, dex = 76, }, +} +itemBases["Despot Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 76, physicalMax = 103, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 66, str = 140, dex = 86, }, +} +itemBases["Void Axe"] = { + type = "Two Handed Axe", + weapon = { physicalMin = 76, physicalMax = 114, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 68, str = 149, dex = 76, }, +} +itemBases["Fleshripper"] = { + type = "Two Handed Axe", + implicit = "40% increased Critical Strike Chance", + weapon = { physicalMin = 80, physicalMax = 125, critChanceBase = 7, attackRateBase = 1.2, }, + req = { level = 70, str = 156, dex = 84, }, +} diff --git a/Items/body.lua b/Items/body.lua new file mode 100644 index 00000000..65e9a9e2 --- /dev/null +++ b/Items/body.lua @@ -0,0 +1,533 @@ +local itemBases = ... + +itemBases["Plate Vest"] = { + type = "Body Armour", + armour = { armourBase = 14, }, + req = { }, +} +itemBases["Chestplate"] = { + type = "Body Armour", + armour = { armourBase = 49, }, + req = { level = 6, str = 25, }, +} +itemBases["Copper Plate"] = { + type = "Body Armour", + armour = { armourBase = 126, }, + req = { level = 17, str = 53, }, +} +itemBases["War Plate"] = { + type = "Body Armour", + armour = { armourBase = 154, }, + req = { level = 21, str = 63, }, +} +itemBases["Full Plate"] = { + type = "Body Armour", + armour = { armourBase = 203, }, + req = { level = 28, str = 81, }, +} +itemBases["Arena Plate"] = { + type = "Body Armour", + armour = { armourBase = 231, }, + req = { level = 32, str = 91, }, +} +itemBases["Lordly Plate"] = { + type = "Body Armour", + armour = { armourBase = 252, }, + req = { level = 35, str = 99, }, +} +itemBases["Bronze Plate"] = { + type = "Body Armour", + armour = { armourBase = 266, }, + req = { level = 37, str = 104, }, +} +itemBases["Battle Plate"] = { + type = "Body Armour", + armour = { armourBase = 294, }, + req = { level = 41, str = 114, }, +} +itemBases["Sun Plate"] = { + type = "Body Armour", + armour = { armourBase = 322, }, + req = { level = 45, str = 124, }, +} +itemBases["Colosseum Plate"] = { + type = "Body Armour", + armour = { armourBase = 350, }, + req = { level = 49, str = 134, }, +} +itemBases["Majestic Plate"] = { + type = "Body Armour", + armour = { armourBase = 378, }, + req = { level = 53, str = 144, }, +} +itemBases["Golden Plate"] = { + type = "Body Armour", + armour = { armourBase = 399, }, + req = { level = 56, str = 152, }, +} +itemBases["Crusader Plate"] = { + type = "Body Armour", + armour = { armourBase = 428, }, + req = { level = 59, str = 160, }, +} +itemBases["Astral Plate"] = { + type = "Body Armour", + implicit = "+(8 to 12)% to all Elemental Resistances", + armour = { armourBase = 507, }, + req = { level = 62, str = 180, }, +} +itemBases["Gladiator Plate"] = { + type = "Body Armour", + armour = { armourBase = 526, }, + req = { level = 65, str = 177, }, +} +itemBases["Glorious Plate"] = { + type = "Body Armour", + armour = { armourBase = 553, }, + req = { level = 68, str = 191, }, +} + + +itemBases["Shabby Jerkin"] = { + type = "Body Armour", + armour = { evasionBase = 21, }, + req = { dex = 14, }, +} +itemBases["Strapped Leather"] = { + type = "Body Armour", + armour = { evasionBase = 70, }, + req = { level = 9, dex = 32, }, +} +itemBases["Buckskin Tunic"] = { + type = "Body Armour", + armour = { evasionBase = 126, }, + req = { level = 17, dex = 53, }, +} +itemBases["Wild Leather"] = { + type = "Body Armour", + armour = { evasionBase = 182, }, + req = { level = 25, dex = 73, }, +} +itemBases["Full Leather"] = { + type = "Body Armour", + armour = { evasionBase = 203, }, + req = { level = 28, dex = 81, }, +} +itemBases["Sun Leather"] = { + type = "Body Armour", + armour = { evasionBase = 231, }, + req = { level = 32, dex = 91, }, +} +itemBases["Thief's Garb"] = { + type = "Body Armour", + armour = { evasionBase = 252, }, + req = { level = 35, dex = 99, }, +} +itemBases["Eelskin Tunic"] = { + type = "Body Armour", + armour = { evasionBase = 266, }, + req = { level = 37, dex = 104, }, +} +itemBases["Frontier Leather"] = { + type = "Body Armour", + armour = { evasionBase = 294, }, + req = { level = 41, dex = 114, }, +} +itemBases["Glorious Leather"] = { + type = "Body Armour", + armour = { evasionBase = 322, }, + req = { level = 45, dex = 124, }, +} +itemBases["Coronal Leather"] = { + type = "Body Armour", + armour = { evasionBase = 350, }, + req = { level = 49, dex = 134, }, +} +itemBases["Cutthroat's Garb"] = { + type = "Body Armour", + armour = { evasionBase = 378, }, + req = { level = 53, dex = 144, }, +} +itemBases["Sharkskin Tunic"] = { + type = "Body Armour", + armour = { evasionBase = 399, }, + req = { level = 56, dex = 152, }, +} +itemBases["Destiny Leather"] = { + type = "Body Armour", + armour = { evasionBase = 428, }, + req = { level = 59, dex = 160, }, +} +itemBases["Exquisite Leather"] = { + type = "Body Armour", + armour = { evasionBase = 502, }, + req = { level = 62, dex = 170, }, +} +itemBases["Zodiac Leather"] = { + type = "Body Armour", + armour = { evasionBase = 609, }, + req = { level = 65, dex = 197, }, +} +itemBases["Assassin's Garb"] = { + type = "Body Armour", + implicit = "3% increased Movement Speed", + armour = { evasionBase = 525, }, + req = { level = 68, dex = 183, }, +} + + +itemBases["Simple Robe"] = { + type = "Body Armour", + armour = { energyShieldBase = 11, }, + req = { int = 17, }, +} +itemBases["Silken Vest"] = { + type = "Body Armour", + armour = { energyShieldBase = 27, }, + req = { level = 11, int = 37, }, +} +itemBases["Scholar's Robe"] = { + type = "Body Armour", + armour = { energyShieldBase = 41, }, + req = { level = 18, int = 55, }, +} +itemBases["Silken Garb"] = { + type = "Body Armour", + armour = { energyShieldBase = 55, }, + req = { level = 25, int = 73, }, +} +itemBases["Mage's Vestment"] = { + type = "Body Armour", + armour = { energyShieldBase = 61, }, + req = { level = 28, int = 81, }, +} +itemBases["Silk Robe"] = { + type = "Body Armour", + armour = { energyShieldBase = 69, }, + req = { level = 32, int = 91, }, +} +itemBases["Cabalist Regalia"] = { + type = "Body Armour", + armour = { energyShieldBase = 75, }, + req = { level = 35, int = 99, }, +} +itemBases["Sage's Robe"] = { + type = "Body Armour", + armour = { energyShieldBase = 79, }, + req = { level = 37, int = 104, }, +} +itemBases["Silken Wrap"] = { + type = "Body Armour", + armour = { energyShieldBase = 87, }, + req = { level = 41, int = 114, }, +} +itemBases["Conjurer's Vestment"] = { + type = "Body Armour", + armour = { energyShieldBase = 95, }, + req = { level = 45, int = 124, }, +} +itemBases["Spidersilk Robe"] = { + type = "Body Armour", + armour = { energyShieldBase = 103, }, + req = { level = 49, int = 134, }, +} +itemBases["Destroyer Regalia"] = { + type = "Body Armour", + armour = { energyShieldBase = 111, }, + req = { level = 53, int = 144, }, +} +itemBases["Savant's Robe"] = { + type = "Body Armour", + armour = { energyShieldBase = 117, }, + req = { level = 56, int = 152, }, +} +itemBases["Necromancer Silks"] = { + type = "Body Armour", + armour = { energyShieldBase = 125, }, + req = { level = 59, int = 160, }, +} +itemBases["Occultist's Vestment"] = { + type = "Body Armour", + implicit = "(3 to 10)% increased Spell Damage", + armour = { energyShieldBase = 140, }, + req = { level = 62, int = 180, }, +} +itemBases["Widowsilk Robe"] = { + type = "Body Armour", + armour = { energyShieldBase = 161, }, + req = { level = 65, int = 187, }, +} +itemBases["Vaal Regalia"] = { + type = "Body Armour", + armour = { energyShieldBase = 175, }, + req = { level = 68, int = 194, }, +} + + +itemBases["Scale Vest"] = { + type = "Body Armour", + armour = { armourBase = 19, evasionBase = 19, }, + req = { }, +} +itemBases["Light Brigandine"] = { + type = "Body Armour", + armour = { armourBase = 35, evasionBase = 35, }, + req = { level = 8, str = 16, dex = 16, }, +} +itemBases["Scale Doublet"] = { + type = "Body Armour", + armour = { armourBase = 69, evasionBase = 69, }, + req = { level = 17, str = 28, dex = 28, }, +} +itemBases["Infantry Brigandine"] = { + type = "Body Armour", + armour = { armourBase = 85, evasionBase = 85, }, + req = { level = 21, str = 34, dex = 34, }, +} +itemBases["Full Scale Armour"] = { + type = "Body Armour", + armour = { armourBase = 112, evasionBase = 112, }, + req = { level = 28, str = 43, dex = 43, }, +} +itemBases["Soldier's Brigandine"] = { + type = "Body Armour", + armour = { armourBase = 127, evasionBase = 127, }, + req = { level = 32, str = 48, dex = 48, }, +} +itemBases["Field Lamellar"] = { + type = "Body Armour", + armour = { armourBase = 138, evasionBase = 138, }, + req = { level = 35, str = 53, dex = 53, }, +} +itemBases["Wyrmscale Doublet"] = { + type = "Body Armour", + armour = { armourBase = 150, evasionBase = 150, }, + req = { level = 38, str = 57, dex = 57, }, +} +itemBases["Hussar Brigandine"] = { + type = "Body Armour", + armour = { armourBase = 165, evasionBase = 165, }, + req = { level = 42, str = 62, dex = 62, }, +} +itemBases["Full Wyrmscale"] = { + type = "Body Armour", + armour = { armourBase = 181, evasionBase = 181, }, + req = { level = 46, str = 68, dex = 68, }, +} +itemBases["Commander's Brigandine"] = { + type = "Body Armour", + armour = { armourBase = 196, evasionBase = 196, }, + req = { level = 50, str = 73, dex = 73, }, +} +itemBases["Battle Lamellar"] = { + type = "Body Armour", + armour = { armourBase = 212, evasionBase = 212, }, + req = { level = 54, str = 79, dex = 79, }, +} +itemBases["Dragonscale Doublet"] = { + type = "Body Armour", + armour = { armourBase = 223, evasionBase = 223, }, + req = { level = 57, str = 83, dex = 83, }, +} +itemBases["Desert Brigandine"] = { + type = "Body Armour", + armour = { armourBase = 268, evasionBase = 268, }, + req = { level = 60, str = 96, dex = 96, }, +} +itemBases["Full Dragonscale"] = { + type = "Body Armour", + armour = { armourBase = 335, evasionBase = 266, }, + req = { level = 63, str = 115, dex = 94, }, +} +itemBases["General's Brigandine"] = { + type = "Body Armour", + armour = { armourBase = 296, evasionBase = 296, }, + req = { level = 66, str = 103, dex = 103, }, +} +itemBases["Triumphant Lamellar"] = { + type = "Body Armour", + armour = { armourBase = 271, evasionBase = 340, }, + req = { level = 69, str = 95, dex = 116, }, +} + + +itemBases["Chainmail Vest"] = { + type = "Body Armour", + armour = { armourBase = 19, energyShieldBase = 7, }, + req = { }, +} +itemBases["Chainmail Tunic"] = { + type = "Body Armour", + armour = { armourBase = 35, energyShieldBase = 11, }, + req = { level = 8, str = 16, int = 16, }, +} +itemBases["Ringmail Coat"] = { + type = "Body Armour", + armour = { armourBase = 69, energyShieldBase = 21, }, + req = { level = 17, str = 28, int = 28, }, +} +itemBases["Chainmail Doublet"] = { + type = "Body Armour", + armour = { armourBase = 85, energyShieldBase = 26, }, + req = { level = 21, str = 34, int = 34, }, +} +itemBases["Full Ringmail"] = { + type = "Body Armour", + armour = { armourBase = 112, energyShieldBase = 33, }, + req = { level = 28, str = 43, int = 43, }, +} +itemBases["Full Chainmail"] = { + type = "Body Armour", + armour = { armourBase = 127, energyShieldBase = 38, }, + req = { level = 32, str = 48, int = 48, }, +} +itemBases["Holy Chainmail"] = { + type = "Body Armour", + armour = { armourBase = 138, energyShieldBase = 41, }, + req = { level = 35, str = 53, int = 53, }, +} +itemBases["Latticed Ringmail"] = { + type = "Body Armour", + armour = { armourBase = 154, energyShieldBase = 46, }, + req = { level = 39, str = 59, int = 59, }, +} +itemBases["Crusader Chainmail"] = { + type = "Body Armour", + armour = { armourBase = 169, energyShieldBase = 50, }, + req = { level = 43, str = 64, int = 64, }, +} +itemBases["Ornate Ringmail"] = { + type = "Body Armour", + armour = { armourBase = 185, energyShieldBase = 54, }, + req = { level = 47, str = 69, int = 69, }, +} +itemBases["Chain Hauberk"] = { + type = "Body Armour", + armour = { armourBase = 200, energyShieldBase = 59, }, + req = { level = 51, str = 75, int = 75, }, +} +itemBases["Devout Chainmail"] = { + type = "Body Armour", + armour = { armourBase = 215, energyShieldBase = 63, }, + req = { level = 55, str = 80, int = 80, }, +} +itemBases["Loricated Ringmail"] = { + type = "Body Armour", + armour = { armourBase = 232, energyShieldBase = 68, }, + req = { level = 58, str = 84, int = 84, }, +} +itemBases["Conquest Chainmail"] = { + type = "Body Armour", + armour = { armourBase = 276, energyShieldBase = 81, }, + req = { level = 61, str = 96, int = 96, }, +} +itemBases["Elegant Ringmail"] = { + type = "Body Armour", + armour = { armourBase = 269, energyShieldBase = 94, }, + req = { level = 64, str = 90, int = 105, }, +} +itemBases["Saint's Hauberk"] = { + type = "Body Armour", + armour = { armourBase = 315, energyShieldBase = 78, }, + req = { level = 67, str = 109, int = 94, }, +} +itemBases["Saintly Chainmail"] = { + type = "Body Armour", + armour = { armourBase = 286, energyShieldBase = 98, }, + req = { level = 70, str = 99, int = 115, }, +} + + +itemBases["Padded Vest"] = { + type = "Body Armour", + armour = { evasionBase = 19, energyShieldBase = 7, }, + req = { }, +} +itemBases["Oiled Vest"] = { + type = "Body Armour", + armour = { evasionBase = 38, energyShieldBase = 13, }, + req = { level = 9, dex = 17, int = 17, }, +} +itemBases["Padded Jacket"] = { + type = "Body Armour", + armour = { evasionBase = 73, energyShieldBase = 22, }, + req = { level = 18, dex = 30, int = 30, }, +} +itemBases["Oiled Coat"] = { + type = "Body Armour", + armour = { evasionBase = 88, energyShieldBase = 27, }, + req = { level = 22, dex = 35, int = 35, }, +} +itemBases["Scarlet Raiment"] = { + type = "Body Armour", + armour = { evasionBase = 112, energyShieldBase = 33, }, + req = { level = 28, dex = 43, int = 43, }, +} +itemBases["Waxed Garb"] = { + type = "Body Armour", + armour = { evasionBase = 127, energyShieldBase = 38, }, + req = { level = 32, dex = 48, int = 48, }, +} +itemBases["Bone Armour"] = { + type = "Body Armour", + armour = { evasionBase = 138, energyShieldBase = 41, }, + req = { level = 35, dex = 53, int = 53, }, +} +itemBases["Quilted Jacket"] = { + type = "Body Armour", + armour = { evasionBase = 158, energyShieldBase = 47, }, + req = { level = 40, dex = 60, int = 60, }, +} +itemBases["Sleek Coat"] = { + type = "Body Armour", + armour = { evasionBase = 173, energyShieldBase = 51, }, + req = { level = 44, dex = 65, int = 65, }, +} +itemBases["Crimson Raiment"] = { + type = "Body Armour", + armour = { evasionBase = 189, energyShieldBase = 55, }, + req = { level = 48, dex = 71, int = 71, }, +} +itemBases["Lacquered Garb"] = { + type = "Body Armour", + armour = { evasionBase = 204, energyShieldBase = 60, }, + req = { level = 52, dex = 76, int = 76, }, +} +itemBases["Crypt Armour"] = { + type = "Body Armour", + armour = { evasionBase = 219, energyShieldBase = 64, }, + req = { level = 56, dex = 82, int = 82, }, +} +itemBases["Sentinel Jacket"] = { + type = "Body Armour", + armour = { evasionBase = 235, energyShieldBase = 69, }, + req = { level = 59, dex = 86, int = 86, }, +} +itemBases["Varnished Coat"] = { + type = "Body Armour", + armour = { evasionBase = 276, energyShieldBase = 81, }, + req = { level = 62, dex = 96, int = 96, }, +} +itemBases["Blood Raiment"] = { + type = "Body Armour", + armour = { evasionBase = 311, energyShieldBase = 75, }, + req = { level = 65, dex = 107, int = 90, }, +} +itemBases["Sadist Garb"] = { + type = "Body Armour", + armour = { evasionBase = 304, energyShieldBase = 95, }, + req = { level = 68, dex = 103, int = 109, }, +} +itemBases["Carnal Armour"] = { + type = "Body Armour", + implicit = "+(20 to 25) to maximum Mana", + armour = { evasionBase = 251, energyShieldBase = 105, }, + req = { level = 71, dex = 88, int = 122, }, +} + + +itemBases["Sacrificial Garb"] = { + type = "Body Armour", + armour = { armourBase = 234, evasionNase = 234, energyShieldBase = 69, }, + req = { level = 72, str = 66, dex = 66, int = 66, }, +} diff --git a/Items/boots.lua b/Items/boots.lua new file mode 100644 index 00000000..23bc340e --- /dev/null +++ b/Items/boots.lua @@ -0,0 +1,272 @@ +local itemBases = ... + +itemBases["Iron Greaves"] = { + type = "Boots", + armour = { armourBase = 6, }, + req = { }, +} +itemBases["Steel Greaves"] = { + type = "Boots", + armour = { armourBase = 28, }, + req = { level = 9, str = 21, }, +} +itemBases["Plated Greaves"] = { + type = "Boots", + armour = { armourBase = 67, }, + req = { level = 23, str = 44, }, +} +itemBases["Reinforced Greaves"] = { + type = "Boots", + armour = { armourBase = 95, }, + req = { level = 33, str = 60, }, +} +itemBases["Antique Greaves"] = { + type = "Boots", + armour = { armourBase = 106, }, + req = { level = 37, str = 67, }, +} +itemBases["Ancient Greaves"] = { + type = "Boots", + armour = { armourBase = 132, }, + req = { level = 46, str = 82, }, +} +itemBases["Goliath Greaves"] = { + type = "Boots", + armour = { armourBase = 154, }, + req = { level = 54, str = 95, }, +} +itemBases["Vaal Greaves"] = { + type = "Boots", + armour = { armourBase = 191, }, + req = { level = 62, str = 117, }, +} +itemBases["Titan Greaves"] = { + type = "Boots", + armour = { armourBase = 210, }, + req = { level = 68, str = 120, }, +} + + +itemBases["Rawhide Boots"] = { + type = "Boots", + armour = { evasionBase = 11, }, + req = { }, +} +itemBases["Goathide Boots"] = { + type = "Boots", + armour = { evasionBase = 36, }, + req = { level = 12, dex = 26, }, +} +itemBases["Deerskin Boots"] = { + type = "Boots", + armour = { evasionBase = 64, }, + req = { level = 22, dex = 42, }, +} +itemBases["Nubuck Boots"] = { + type = "Boots", + armour = { evasionBase = 98, }, + req = { level = 34, dex = 62, }, +} +itemBases["Eelskin Boots"] = { + type = "Boots", + armour = { evasionBase = 112, }, + req = { level = 39, dex = 70, }, +} +itemBases["Sharkskin Boots"] = { + type = "Boots", + armour = { evasionBase = 126, }, + req = { level = 44, dex = 79, }, +} +itemBases["Shagreen Boots"] = { + type = "Boots", + armour = { evasionBase = 157, }, + req = { level = 55, dex = 97, }, +} +itemBases["Stealth Boots"] = { + type = "Boots", + armour = { evasionBase = 191, }, + req = { level = 62, dex = 117, }, +} +itemBases["Slink Boots"] = { + type = "Boots", + armour = { evasionBase = 214, }, + req = { level = 69, dex = 120, }, +} + + +itemBases["Wool Shoes"] = { + type = "Boots", + armour = { energyShieldBase = 4, }, + req = { }, +} +itemBases["Velvet Slippers"] = { + type = "Boots", + armour = { energyShieldBase = 9, }, + req = { level = 9, int = 21, }, +} +itemBases["Silk Slippers"] = { + type = "Boots", + armour = { energyShieldBase = 20, }, + req = { level = 22, int = 42, }, +} +itemBases["Scholar Boots"] = { + type = "Boots", + armour = { energyShieldBase = 28, }, + req = { level = 32, int = 59, }, +} +itemBases["Satin Slippers"] = { + type = "Boots", + armour = { energyShieldBase = 32, }, + req = { level = 38, int = 69, }, +} +itemBases["Samite Slippers"] = { + type = "Boots", + armour = { energyShieldBase = 37, }, + req = { level = 44, int = 79, }, +} +itemBases["Conjurer Boots"] = { + type = "Boots", + armour = { energyShieldBase = 44, }, + req = { level = 53, int = 94, }, +} +itemBases["Arcanist Slippers"] = { + type = "Boots", + armour = { energyShieldBase = 59, }, + req = { level = 61, int = 119, }, +} +itemBases["Sorcerer Boots"] = { + type = "Boots", + armour = { energyShieldBase = 64, }, + req = { level = 67, int = 123, }, +} + + +itemBases["Leatherscale Boots"] = { + type = "Boots", + armour = { armourBase = 11, evasionBase = 11, }, + req = { level = 6, }, +} +itemBases["Ironscale Boots"] = { + type = "Boots", + armour = { armourBase = 29, evasionBase = 29, }, + req = { level = 18, str = 19, dex = 19, }, +} +itemBases["Bronzescale Boots"] = { + type = "Boots", + armour = { armourBase = 48, evasionBase = 48, }, + req = { level = 30, str = 30, dex = 30, }, +} +itemBases["Steelscale Boots"] = { + type = "Boots", + armour = { armourBase = 57, evasionBase = 57, }, + req = { level = 36, str = 35, dex = 35, }, +} +itemBases["Serpentscale Boots"] = { + type = "Boots", + armour = { armourBase = 66, evasionBase = 66, }, + req = { level = 42, str = 40, dex = 40, }, +} +itemBases["Wyrmscale Boots"] = { + type = "Boots", + armour = { armourBase = 80, evasionBase = 80, }, + req = { level = 51, str = 48, dex = 48, }, +} +itemBases["Hydrascale Boots"] = { + type = "Boots", + armour = { armourBase = 92, evasionBase = 92, }, + req = { level = 59, str = 56, dex = 56, }, +} +itemBases["Dragonscale Boots"] = { + type = "Boots", + armour = { armourBase = 105, evasionBase = 105, }, + req = { level = 65, str = 62, dex = 62, }, +} + + +itemBases["Chain Boots"] = { + type = "Boots", + armour = { armourBase = 9, energyShieldBase = 3, }, + req = { level = 5, }, +} +itemBases["Ringmail Boots"] = { + type = "Boots", + armour = { armourBase = 22, energyShieldBase = 7, }, + req = { level = 13, str = 15, int = 15, }, +} +itemBases["Mesh Boots"] = { + type = "Boots", + armour = { armourBase = 45, energyShieldBase = 13, }, + req = { level = 28, str = 28, int = 28, }, +} +itemBases["Riveted Boots"] = { + type = "Boots", + armour = { armourBase = 57, energyShieldBase = 17, }, + req = { level = 36, str = 35, int = 35, }, +} +itemBases["Zealot Boots"] = { + type = "Boots", + armour = { armourBase = 63, energyShieldBase = 19, }, + req = { level = 40, str = 38, int = 38, }, +} +itemBases["Soldier Boots"] = { + type = "Boots", + armour = { armourBase = 77, energyShieldBase = 23, }, + req = { level = 49, str = 47, int = 47, }, +} +itemBases["Legion Boots"] = { + type = "Boots", + armour = { armourBase = 91, energyShieldBase = 27, }, + req = { level = 58, str = 54, int = 54, }, +} +itemBases["Crusader Boots"] = { + type = "Boots", + armour = { armourBase = 105, energyShieldBase = 31, }, + req = { level = 64, str = 62, int = 62, }, +} + + +itemBases["Wrapped Boots"] = { + type = "Boots", + armour = { evasionBase = 11, energyShieldBase = 4, }, + req = { level = 6, }, +} +itemBases["Strapped Boots"] = { + type = "Boots", + armour = { evasionBase = 26, energyShieldBase = 8, }, + req = { level = 16, dex = 18, int = 18, }, +} +itemBases["Clasped Boots"] = { + type = "Boots", + armour = { evasionBase = 43, energyShieldBase = 13, }, + req = { level = 27, dex = 27, int = 27, }, +} +itemBases["Shackled Boots"] = { + type = "Boots", + armour = { evasionBase = 54, energyShieldBase = 16, }, + req = { level = 34, dex = 34, int = 34, }, +} +itemBases["Trapper Boots"] = { + type = "Boots", + armour = { evasionBase = 65, energyShieldBase = 19, }, + req = { level = 41, dex = 40, int = 40, }, +} +itemBases["Ambush Boots"] = { + type = "Boots", + armour = { evasionBase = 74, energyShieldBase = 22, }, + req = { level = 47, dex = 45, int = 45, }, +} +itemBases["Carnal Boots"] = { + type = "Boots", + armour = { evasionBase = 86, energyShieldBase = 25, }, + req = { level = 55, dex = 52, int = 52, }, +} +itemBases["Assassin's Boots"] = { + type = "Boots", + armour = { evasionBase = 105, energyShieldBase = 31, }, + req = { level = 63, dex = 62, int = 62, }, +} +itemBases["Murder Boots"] = { + type = "Boots", + armour = { evasionBase = 161, energyShieldBase = 22, }, + req = { level = 69, dex = 82, int = 42, }, +} diff --git a/Items/bow.lua b/Items/bow.lua new file mode 100644 index 00000000..55695935 --- /dev/null +++ b/Items/bow.lua @@ -0,0 +1,136 @@ +local itemBases = ... + +itemBases["Crude Bow"] = { + type = "Bow", + weapon = { physicalMin = 5, physicalMax = 13, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 1, dex = 14, }, +} +itemBases["Short Bow"] = { + type = "Bow", + weapon = { physicalMin = 6, physicalMax = 16, critChanceBase = 5, attackRateBase = 1.5, }, + req = { level = 5, dex = 26, }, +} +itemBases["Long Bow"] = { + type = "Bow", + weapon = { physicalMin = 6, physicalMax = 25, critChanceBase = 6, attackRateBase = 1.3, }, + req = { level = 9, dex = 38, }, +} +itemBases["Composite Bow"] = { + type = "Bow", + weapon = { physicalMin = 12, physicalMax = 26, critChanceBase = 6, attackRateBase = 1.3, }, + req = { level = 14, dex = 53, }, +} +itemBases["Recurve Bow"] = { + type = "Bow", + weapon = { physicalMin = 11, physicalMax = 34, critChanceBase = 6.5, attackRateBase = 1.25, }, + req = { level = 18, dex = 65, }, +} +itemBases["Bone Bow"] = { + type = "Bow", + weapon = { physicalMin = 12, physicalMax = 36, critChanceBase = 6, attackRateBase = 1.35, }, + req = { level = 23, dex = 80, }, +} +itemBases["Royal Bow"] = { + type = "Bow", + implicit = "(6 to 12)% increased Elemental Damage with Weapons", + weapon = { physicalMin = 10, physicalMax = 41, critChanceBase = 5, attackRateBase = 1.45, }, + req = { level = 28, dex = 95, }, +} +itemBases["Death Bow"] = { + type = "Bow", + implicit = "(30 to 50)% increased Critical Strike Chance", + weapon = { physicalMin = 20, physicalMax = 53, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 32, dex = 107, }, +} +itemBases["Grove Bow"] = { + type = "Bow", + weapon = { physicalMin = 15, physicalMax = 44, critChanceBase = 5, attackRateBase = 1.5, }, + req = { level = 35, dex = 116, }, +} +itemBases["Reflex Bow"] = { + type = "Bow", + implicit = "4% increased Movement Speed", + weapon = { physicalMin = 27, physicalMax = 40, critChanceBase = 5.5, attackRateBase = 1.4, }, + req = { level = 36, dex = 124, }, +} +itemBases["Decurve Bow"] = { + type = "Bow", + weapon = { physicalMin = 17, physicalMax = 70, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 38, dex = 125, }, +} +itemBases["Compound Bow"] = { + type = "Bow", + weapon = { physicalMin = 24, physicalMax = 56, critChanceBase = 6, attackRateBase = 1.3, }, + req = { level = 41, dex = 134, }, +} +itemBases["Sniper Bow"] = { + type = "Bow", + weapon = { physicalMin = 23, physicalMax = 68, critChanceBase = 6.5, attackRateBase = 1.25, }, + req = { level = 44, dex = 143, }, +} +itemBases["Ivory Bow"] = { + type = "Bow", + weapon = { physicalMin = 21, physicalMax = 64, critChanceBase = 6, attackRateBase = 1.35, }, + req = { level = 47, dex = 152, }, +} +itemBases["Highborn Bow"] = { + type = "Bow", + implicit = "(6 to 12)% increased Elemental Damage with Weapons", + weapon = { physicalMin = 17, physicalMax = 66, critChanceBase = 5, attackRateBase = 1.45, }, + req = { level = 50, dex = 161, }, +} +itemBases["Decimation Bow"] = { + type = "Bow", + implicit = "(30 to 50)% increased Critical Strike Chance", + weapon = { physicalMin = 31, physicalMax = 81, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 53, dex = 170, }, +} +itemBases["Thicket Bow"] = { + type = "Bow", + weapon = { physicalMin = 22, physicalMax = 66, critChanceBase = 5, attackRateBase = 1.5, }, + req = { level = 56, dex = 179, }, +} +itemBases["Steelwood Bow"] = { + type = "Bow", + implicit = "4% increased Movement Speed", + weapon = { physicalMin = 40, physicalMax = 60, critChanceBase = 5.5, attackRateBase = 1.4, }, + req = { level = 57, dex = 190, }, +} +itemBases["Citadel Bow"] = { + type = "Bow", + weapon = { physicalMin = 25, physicalMax = 101, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 58, dex = 185, }, +} +itemBases["Ranger Bow"] = { + type = "Bow", + weapon = { physicalMin = 34, physicalMax = 79, critChanceBase = 6, attackRateBase = 1.3, }, + req = { level = 60, dex = 212, }, +} +itemBases["Assassin Bow"] = { + type = "Bow", + weapon = { physicalMin = 30, physicalMax = 89, critChanceBase = 6.5, attackRateBase = 1.25, }, + req = { level = 62, dex = 212, }, +} +itemBases["Spine Bow"] = { + type = "Bow", + weapon = { physicalMin = 27, physicalMax = 80, critChanceBase = 6, attackRateBase = 1.35, }, + req = { level = 64, dex = 212, }, +} +itemBases["Imperial Bow"] = { + type = "Bow", + implicit = "(6 to 12)% increased Elemental Damage with Weapons", + weapon = { physicalMin = 19, physicalMax = 78, critChanceBase = 5, attackRateBase = 1.45, }, + req = { level = 66, dex = 212, }, +} +itemBases["Harbinger Bow"] = { + type = "Bow", + implicit = "(30 to 50)% increased Critical Strike Chance", + weapon = { physicalMin = 35, physicalMax = 91, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 68, dex = 212, }, +} +itemBases["Maraketh Bow"] = { + type = "Bow", + implicit = "6% increased Movement Speed", + weapon = { physicalMin = 44, physicalMax = 65, critChanceBase = 5.5, attackRateBase = 1.4, }, + req = { level = 71, dex = 222, }, +} diff --git a/Items/claw.lua b/Items/claw.lua new file mode 100644 index 00000000..dac6708c --- /dev/null +++ b/Items/claw.lua @@ -0,0 +1,154 @@ +local itemBases = ... + +itemBases["Nailed Fist"] = { + type = "Claw", + implicit = "+3 Life gained for each enemy hit by your Attacks", + weapon = { physicalMin = 4, physicalMax = 9, critChanceBase = 6.2, attackRateBase = 1.6, }, + req = { level = 3, dex = 11, int = 11, }, +} +itemBases["Sharktooth Claw"] = { + type = "Claw", + implicit = "+6 Life gained for each enemy hit by your Attacks", + weapon = { physicalMin = 6, physicalMax = 15, critChanceBase = 6.5, attackRateBase = 1.4, }, + req = { level = 7, dex = 14, int = 20, }, +} +itemBases["Awl"] = { + type = "Claw", + implicit = "+5 Life gained for each enemy hit by your Attacks", + weapon = { physicalMin = 6, physicalMax = 20, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 12, dex = 25, int = 25, }, +} +itemBases["Cat's Paw"] = { + type = "Claw", + implicit = "1.6% of Physical Attack Damage Leeched as Life", + weapon = { physicalMin = 10, physicalMax = 19, critChanceBase = 6, attackRateBase = 1.6, }, + req = { level = 17, dex = 39, int = 27, }, +} +itemBases["Blinder"] = { + type = "Claw", + implicit = "+10 Life gained for each enemy hit by your Attacks", + weapon = { physicalMin = 10, physicalMax = 27, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 22, dex = 41, int = 41, }, +} +itemBases["Timeworn Claw"] = { + type = "Claw", + implicit = "2% of Physical Attack Damage Leeched as Life", + weapon = { physicalMin = 14, physicalMax = 36, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 26, dex = 39, int = 56, }, +} +itemBases["Sparkling Claw"] = { + type = "Claw", + implicit = "+10 Life gained for each enemy hit by your Attacks", + weapon = { physicalMin = 12, physicalMax = 32, critChanceBase = 6, attackRateBase = 1.6, }, + req = { level = 30, dex = 64, int = 44, }, +} +itemBases["Fright Claw"] = { + type = "Claw", + implicit = "2% of Physical Attack Damage Leeched as Life", + weapon = { physicalMin = 9, physicalMax = 37, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 34, dex = 61, int = 61, }, +} +itemBases["Double Claw"] = { + type = "Claw", + implicit = "+6 Life and Mana gained for each Enemy hit", + weapon = { physicalMin = 13, physicalMax = 40, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 36, dex = 67, int = 67, }, +} +itemBases["Thresher Claw"] = { + type = "Claw", + implicit = "+21 Life gained for each Enemy hit by Attacks", + weapon = { physicalMin = 18, physicalMax = 48, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 37, dex = 53, int = 77, }, +} +itemBases["Gouger"] = { + type = "Claw", + implicit = "+13 Life gained for each enemy hit by your Attacks", + weapon = { physicalMin = 13, physicalMax = 46, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 40, dex = 70, int = 70, }, +} +itemBases["Tiger's Paw"] = { + type = "Claw", + implicit = "1.6% of Physical Attack Damage Leeched as Life", + weapon = { physicalMin = 21, physicalMax = 38, critChanceBase = 6, attackRateBase = 1.6, }, + req = { level = 43, dex = 88, int = 61, }, +} +itemBases["Gut Ripper"] = { + type = "Claw", + implicit = "+21 Life gained for each enemy hit by your Attacks", + weapon = { physicalMin = 18, physicalMax = 48, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 46, dex = 80, int = 80, }, +} +itemBases["Prehistoric Claw"] = { + type = "Claw", + implicit = "2% of Physical Attack Damage Leeched as Life", + weapon = { physicalMin = 23, physicalMax = 61, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 49, dex = 69, int = 100, }, +} +itemBases["Noble Claw"] = { + type = "Claw", + implicit = "+18 Life gained for each Enemy hit by Attacks", + weapon = { physicalMin = 19, physicalMax = 50, critChanceBase = 6, attackRateBase = 1.6, }, + req = { level = 52, dex = 105, int = 73, }, +} +itemBases["Eagle Claw"] = { + type = "Claw", + implicit = "2% of Physical Attack Damage Leeched as Life", + weapon = { physicalMin = 14, physicalMax = 56, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 55, dex = 94, int = 94, }, +} +itemBases["Twin Claw"] = { + type = "Claw", + implicit = "+10 Life and Mana gained for each Enemy hit", + weapon = { physicalMin = 20, physicalMax = 60, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 57, dex = 103, int = 103, }, +} +itemBases["Great White Claw"] = { + type = "Claw", + implicit = "+34 Life gained for each Enemy hit by Attacks", + weapon = { physicalMin = 27, physicalMax = 70, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 58, dex = 81, int = 117, }, +} +itemBases["Throat Stabber"] = { + type = "Claw", + implicit = "+21 Life gained for each Enemy hit by Attacks", + weapon = { physicalMin = 19, physicalMax = 65, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 60, dex = 113, int = 113, }, +} +itemBases["Hellion's Paw"] = { + type = "Claw", + implicit = "1.6% of Physical Attack Damage Leeched as Life", + weapon = { physicalMin = 27, physicalMax = 51, critChanceBase = 6, attackRateBase = 1.6, }, + req = { level = 62, dex = 131, int = 95, }, +} +itemBases["Eye Gouger"] = { + type = "Claw", + implicit = "+31 Life gained for each enemy hit by Attacks", + weapon = { physicalMin = 23, physicalMax = 61, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 64, dex = 113, int = 113, }, +} +itemBases["Vaal Claw"] = { + type = "Claw", + implicit = "2% of Physical Attack Damage Leeched as Life", + weapon = { physicalMin = 27, physicalMax = 72, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 66, dex = 95, int = 131, }, +} +itemBases["Imperial Claw"] = { + type = "Claw", + implicit = "+25 Life gained for each Enemy hit by Attacks", + weapon = { physicalMin = 22, physicalMax = 57, critChanceBase = 6, attackRateBase = 1.6, }, + req = { level = 68, dex = 131, int = 95, }, +} +itemBases["Terror Claw"] = { + type = "Claw", + implicit = "2% of Physical Attack Damage Leeched as Life", + weapon = { physicalMin = 15, physicalMax = 60, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 70, dex = 113, int = 113, }, +} +itemBases["Gemini Claw"] = { + type = "Claw", + implicit = "+14 Life and Mana gained for each Enemy hit", + weapon = { physicalMin = 21, physicalMax = 63, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 72, dex = 121, int = 121, }, +} + + diff --git a/Items/dagger.lua b/Items/dagger.lua new file mode 100644 index 00000000..4cac2cb2 --- /dev/null +++ b/Items/dagger.lua @@ -0,0 +1,152 @@ +local itemBases = ... + +itemBases["Glass Shank"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 3, physicalMax = 10, critChanceBase = 6, attackRateBase = 1.5, }, + req = { level = 1, dex = 9, int = 6, }, +} +itemBases["Skinning Knife"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 4, physicalMax = 16, critChanceBase = 6, attackRateBase = 1.3, }, + req = { level = 5, dex = 16, int = 11, }, +} +itemBases["Carving Knife"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 2, physicalMax = 22, critChanceBase = 6.6, attackRateBase = 1.4, }, + req = { level = 10, dex = 18, int = 26, }, +} +itemBases["Stiletto"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 6, physicalMax = 23, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 15, dex = 30, int = 30, }, +} +itemBases["Boot Knife"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 8, physicalMax = 30, critChanceBase = 6.6, attackRateBase = 1.4, }, + req = { level = 20, dex = 31, int = 45, }, +} +itemBases["Copper Kris"] = { + type = "Dagger", + implicit = "80% increased Global Critical Strike Chance", + weapon = { physicalMin = 10, physicalMax = 39, critChanceBase = 7, attackRateBase = 1.2, }, + req = { level = 24, dex = 28, int = 60, }, +} +itemBases["Skean"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 9, physicalMax = 37, critChanceBase = 6.6, attackRateBase = 1.45, }, + req = { level = 28, dex = 42, int = 60, }, +} +itemBases["Imp Dagger"] = { + type = "Dagger", + implicit = "60% increased Global Critical Strike Chance", + weapon = { physicalMin = 12, physicalMax = 49, critChanceBase = 7, attackRateBase = 1.2, }, + req = { level = 32, dex = 36, int = 78, }, +} +itemBases["Prong Dagger"] = { + type = "Dagger", + implicit = "4% Chance to Block", + weapon = { physicalMin = 13, physicalMax = 51, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 36, dex = 55, int = 77, }, +} +itemBases["Flaying Knife"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 14, physicalMax = 56, critChanceBase = 6, attackRateBase = 1.2, }, + req = { level = 35, dex = 73, int = 51, }, +} +itemBases["Butcher Knife"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 6, physicalMax = 54, critChanceBase = 6.6, attackRateBase = 1.4, }, + req = { level = 38, dex = 55, int = 79, }, +} +itemBases["Poignard"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 12, physicalMax = 48, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 41, dex = 72, int = 72, }, +} +itemBases["Boot Blade"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 14, physicalMax = 55, critChanceBase = 6.6, attackRateBase = 1.4, }, + req = { level = 44, dex = 63, int = 90, }, +} +itemBases["Golden Kris"] = { + type = "Dagger", + implicit = "80% increased Global Critical Strike Chance", + weapon = { physicalMin = 16, physicalMax = 65, critChanceBase = 7, attackRateBase = 1.2, }, + req = { level = 47, dex = 51, int = 110, }, +} +itemBases["Royal Skean"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 15, physicalMax = 59, critChanceBase = 6.6, attackRateBase = 1.45, }, + req = { level = 50, dex = 71, int = 102, }, +} +itemBases["Fiend Dagger"] = { + type = "Dagger", + implicit = "60% increased Global Critical Strike Chance", + weapon = { physicalMin = 19, physicalMax = 76, critChanceBase = 7, attackRateBase = 1.2, }, + req = { level = 53, dex = 58, int = 123, }, +} +itemBases["Trisula"] = { + type = "Dagger", + implicit = "4% Chance to Block", + weapon = { physicalMin = 19, physicalMax = 74, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 55, dex = 89, int = 106, }, +} +itemBases["Gutting Knife"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 21, physicalMax = 84, critChanceBase = 6, attackRateBase = 1.2, }, + req = { level = 56, dex = 113, int = 78, }, +} +itemBases["Slaughter Knife"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 9, physicalMax = 78, critChanceBase = 6.6, attackRateBase = 1.4, }, + req = { level = 58, dex = 81, int = 117, }, +} +itemBases["Ambusher"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 17, physicalMax = 67, critChanceBase = 6.3, attackRateBase = 1.5, }, + req = { level = 60, dex = 113, int = 113, }, +} +itemBases["Ezomyte Dagger"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 18, physicalMax = 72, critChanceBase = 6.6, attackRateBase = 1.4, }, + req = { level = 62, dex = 95, int = 131, }, +} +itemBases["Platinum Kris"] = { + type = "Dagger", + implicit = "80% increased Global Critical Strike Chance", + weapon = { physicalMin = 20, physicalMax = 81, critChanceBase = 7, attackRateBase = 1.2, }, + req = { level = 64, dex = 76, int = 149, }, +} +itemBases["Imperial Skean"] = { + type = "Dagger", + implicit = "40% increased Global Critical Strike Chance", + weapon = { physicalMin = 17, physicalMax = 69, critChanceBase = 6.6, attackRateBase = 1.45, }, + req = { level = 66, dex = 95, int = 131, }, +} +itemBases["Demon Dagger"] = { + type = "Dagger", + implicit = "60% increased Global Critical Strike Chance", + weapon = { physicalMin = 21, physicalMax = 85, critChanceBase = 7, attackRateBase = 1.2, }, + req = { level = 68, dex = 76, int = 149, }, +} +itemBases["Sai"] = { + type = "Dagger", + implicit = "6% Chance to Block", + weapon = { physicalMin = 20, physicalMax = 80, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 70, dex = 121, int = 121, }, +} diff --git a/Items/glove.lua b/Items/glove.lua new file mode 100644 index 00000000..075ae7d0 --- /dev/null +++ b/Items/glove.lua @@ -0,0 +1,267 @@ +local itemBases = ... + +itemBases["Iron Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 6, }, + req = { }, +} +itemBases["Plated Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 34, }, + req = { level = 11, str = 20, }, +} +itemBases["Bronze Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 67, }, + req = { level = 23, str = 36, }, +} +itemBases["Steel Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 101, }, + req = { level = 35, str = 52, }, +} +itemBases["Antique Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 112, }, + req = { level = 39, str = 58, }, +} +itemBases["Ancient Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 134, }, + req = { level = 47, str = 68, }, +} +itemBases["Goliath Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 151, }, + req = { level = 53, str = 76, }, +} +itemBases["Vaal Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 201, }, + req = { level = 63, str = 100, }, +} +itemBases["Titan Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 210, }, + req = { level = 69, str = 98, }, +} + + +itemBases["Rawhide Gloves"] = { + type = "Gloves", + armour = { evasionBase = 11, }, + req = { }, +} +itemBases["Goathide Gloves"] = { + type = "Gloves", + armour = { evasionBase = 28, }, + req = { level = 9, dex = 17, }, +} +itemBases["Deerskin Gloves"] = { + type = "Gloves", + armour = { evasionBase = 62, }, + req = { level = 21, dex = 33, }, +} +itemBases["Nubuck Gloves"] = { + type = "Gloves", + armour = { evasionBase = 95, }, + req = { level = 33, dex = 50, }, +} +itemBases["Eelskin Gloves"] = { + type = "Gloves", + armour = { evasionBase = 109, }, + req = { level = 38, dex = 56, }, +} +itemBases["Sharkskin Gloves"] = { + type = "Gloves", + armour = { evasionBase = 129, }, + req = { level = 45, dex = 66, }, +} +itemBases["Shagreen Gloves"] = { + type = "Gloves", + armour = { evasionBase = 154, }, + req = { level = 54, dex = 78, }, +} +itemBases["Stealth Gloves"] = { + type = "Gloves", + armour = { evasionBase = 200, }, + req = { level = 62, dex = 97, }, +} +itemBases["Slink Gloves"] = { + type = "Gloves", + armour = { evasionBase = 210, }, + req = { level = 70, dex = 95, }, +} + + +itemBases["Wool Gloves"] = { + type = "Gloves", + armour = { energyShieldBase = 4, }, + req = { }, +} +itemBases["Velvet Gloves"] = { + type = "Gloves", + armour = { energyShieldBase = 12, }, + req = { level = 12, int = 21, }, +} +itemBases["Silk Gloves"] = { + type = "Gloves", + armour = { energyShieldBase = 22, }, + req = { level = 25, int = 39, }, +} +itemBases["Embroidered Gloves"] = { + type = "Gloves", + armour = { energyShieldBase = 31, }, + req = { level = 36, int = 54, }, +} +itemBases["Satin Gloves"] = { + type = "Gloves", + armour = { energyShieldBase = 35, }, + req = { level = 41, int = 60, }, +} +itemBases["Samite Gloves"] = { + type = "Gloves", + armour = { energyShieldBase = 40, }, + req = { level = 47, int = 68, }, +} +itemBases["Conjurer Gloves"] = { + type = "Gloves", + armour = { energyShieldBase = 46, }, + req = { level = 55, int = 79, }, +} +itemBases["Arcanist Gloves"] = { + type = "Gloves", + armour = { energyShieldBase = 56, }, + req = { level = 60, int = 95, }, +} +itemBases["Sorcerer Gloves"] = { + type = "Gloves", + armour = { energyShieldBase = 61, }, + req = { level = 69, int = 97, }, +} + + +itemBases["Fishscale Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 8, evasionBase = 8, }, + req = { }, +} +itemBases["Ironscale Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 25, evasionBase = 25, }, + req = { level = 15, }, +} +itemBases["Bronzescale Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 43, evasionBase = 43, }, + req = { level = 27, str = 22, dex = 22, }, +} +itemBases["Steelscale Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 57, evasionBase = 57, }, + req = { level = 36, str = 29, dex = 29, }, +} +itemBases["Serpentscale Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 68, evasionBase = 68, }, + req = { level = 43, str = 34, dex = 34, }, +} +itemBases["Wyrmscale Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 77, evasionBase = 77, }, + req = { level = 49, str = 38, dex = 38, }, +} +itemBases["Hydrascale Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 92, evasionBase = 92, }, + req = { level = 59, str = 45, dex = 45, }, +} +itemBases["Dragonscale Gauntlets"] = { + type = "Gloves", + armour = { armourBase = 105, evasionBase = 105, }, + req = { level = 67, str = 51, dex = 51, }, +} + + +itemBases["Chain Gloves"] = { + type = "Gloves", + armour = { armourBase = 12, energyShieldBase = 4, }, + req = { level = 7, }, +} +itemBases["Ringmail Gloves"] = { + type = "Gloves", + armour = { armourBase = 31, energyShieldBase = 9, }, + req = { level = 19, str = 16, int = 16, }, +} +itemBases["Mesh Gloves"] = { + type = "Gloves", + armour = { armourBase = 51, energyShieldBase = 15, }, + req = { level = 32, str = 26, int = 26, }, +} +itemBases["Riveted Gloves"] = { + type = "Gloves", + armour = { armourBase = 58, energyShieldBase = 17, }, + req = { level = 37, str = 29, int = 29, }, +} +itemBases["Zealot Gloves"] = { + type = "Gloves", + armour = { armourBase = 68, energyShieldBase = 20, }, + req = { level = 43, str = 34, int = 34, }, +} +itemBases["Soldier Gloves"] = { + type = "Gloves", + armour = { armourBase = 80, energyShieldBase = 24, }, + req = { level = 51, str = 40, int = 40, }, +} +itemBases["Legion Gloves"] = { + type = "Gloves", + armour = { armourBase = 89, energyShieldBase = 26, }, + req = { level = 57, str = 44, int = 44, }, +} +itemBases["Crusader Gloves"] = { + type = "Gloves", + armour = { armourBase = 105, energyShieldBase = 31, }, + req = { level = 66, str = 51, int = 51, }, +} + + +itemBases["Wrapped Mitts"] = { + type = "Gloves", + armour = { evasionBase = 9, energyShieldBase = 3, }, + req = { level = 5, }, +} +itemBases["Strapped Mitts"] = { + type = "Gloves", + armour = { evasionBase = 26, energyShieldBase = 8, }, + req = { level = 16, dex = 14, int = 14, }, +} +itemBases["Clasped Mitts"] = { + type = "Gloves", + armour = { evasionBase = 49, energyShieldBase = 15, }, + req = { level = 31, dex = 25, int = 25, }, +} +itemBases["Trapper Mitts"] = { + type = "Gloves", + armour = { evasionBase = 57, energyShieldBase = 17, }, + req = { level = 36, dex = 29, int = 29, }, +} +itemBases["Ambush Mitts"] = { + type = "Gloves", + armour = { evasionBase = 71, energyShieldBase = 21, }, + req = { level = 45, dex = 35, int = 35, }, +} +itemBases["Carnal Mitts"] = { + type = "Gloves", + armour = { evasionBase = 78, energyShieldBase = 23, }, + req = { level = 50, dex = 39, int = 39, }, +} +itemBases["Assassin's Mitts"] = { + type = "Gloves", + armour = { evasionBase = 91, energyShieldBase = 27, }, + req = { level = 58, dex = 45, int = 45, }, +} +itemBases["Murder Mitts"] = { + type = "Gloves", + armour = { evasionBase = 105, energyShieldBase = 31, }, + req = { level = 67, dex = 51, int = 51, }, +} diff --git a/Items/helm.lua b/Items/helm.lua new file mode 100644 index 00000000..f3bca4ef --- /dev/null +++ b/Items/helm.lua @@ -0,0 +1,327 @@ +local itemBases = ... + +itemBases["Iron Hat"] = { + type = "Helmet", + armour = { armourBase = 8, }, + req = { }, +} +itemBases["Cone Helmet"] = { + type = "Helmet", + armour = { armourBase = 33, }, + req = { level = 7, str = 21, }, +} +itemBases["Barbute Helmet"] = { + type = "Helmet", + armour = { armourBase = 80, }, + req = { level = 18, str = 42, }, +} +itemBases["Close Helmet"] = { + type = "Helmet", + armour = { armourBase = 113, }, + req = { level = 26, str = 58, }, +} +itemBases["Gladiator Helmet"] = { + type = "Helmet", + armour = { armourBase = 151, }, + req = { level = 35, str = 75, }, +} +itemBases["Reaver Helmet"] = { + type = "Helmet", + armour = { armourBase = 172, }, + req = { level = 40, str = 85, }, +} +itemBases["Siege Helmet"] = { + type = "Helmet", + armour = { armourBase = 206, }, + req = { level = 48, str = 101, }, +} +itemBases["Samite Helmet"] = { + type = "Helmet", + armour = { armourBase = 240, }, + req = { level = 55, str = 114, }, +} +itemBases["Ezomyte Burgonet"] = { + type = "Helmet", + armour = { armourBase = 301, }, + req = { level = 60, str = 138, }, +} +itemBases["Royal Burgonet"] = { + type = "Helmet", + armour = { armourBase = 328, }, + req = { level = 65, str = 148, }, +} +itemBases["Eternal Burgonet"] = { + type = "Helmet", + armour = { armourBase = 324, }, + req = { level = 69, str = 138, }, +} + + +itemBases["Leather Cap"] = { + type = "Helmet", + armour = { evasionBase = 17, }, + req = { }, +} +itemBases["Tricorne"] = { + type = "Helmet", + armour = { evasionBase = 46, }, + req = { level = 10, dex = 27, }, +} +itemBases["Leather Hood"] = { + type = "Helmet", + armour = { evasionBase = 88, }, + req = { level = 20, dex = 46, }, +} +itemBases["Wolf Pelt"] = { + type = "Helmet", + armour = { evasionBase = 130, }, + req = { level = 30, dex = 66, }, +} +itemBases["Hunter Hood"] = { + type = "Helmet", + armour = { evasionBase = 176, }, + req = { level = 41, dex = 87, }, +} +itemBases["Noble Tricorne"] = { + type = "Helmet", + armour = { evasionBase = 201, }, + req = { level = 47, dex = 99, }, +} +itemBases["Ursine Pelt"] = { + type = "Helmet", + armour = { evasionBase = 240, }, + req = { level = 55, dex = 114, }, +} +itemBases["Silken Hood"] = { + type = "Helmet", + armour = { evasionBase = 301, }, + req = { level = 60, dex = 138, }, +} +itemBases["Sinner Tricorne"] = { + type = "Helmet", + armour = { evasionBase = 321, }, + req = { level = 64, dex = 138, }, +} +itemBases["Lion Pelt"] = { + type = "Helmet", + armour = { evasionBase = 331, }, + req = { level = 70, dex = 150, }, +} + + +itemBases["Vine Circlet"] = { + type = "Helmet", + armour = { energyShieldBase = 7, }, + req = { }, +} +itemBases["Iron Circlet"] = { + type = "Helmet", + armour = { energyShieldBase = 13, }, + req = { level = 8, int = 23, }, +} +itemBases["Torture Cage"] = { + type = "Helmet", + armour = { energyShieldBase = 23, }, + req = { level = 17, int = 40, }, +} +itemBases["Tribal Circlet"] = { + type = "Helmet", + armour = { energyShieldBase = 34, }, + req = { level = 26, int = 58, }, +} +itemBases["Bone Circlet"] = { + type = "Helmet", + armour = { energyShieldBase = 44, }, + req = { level = 34, int = 73, }, +} +itemBases["Lunaris Circlet"] = { + type = "Helmet", + armour = { energyShieldBase = 50, }, + req = { level = 39, int = 83, }, +} +itemBases["Steel Circlet"] = { + type = "Helmet", + armour = { energyShieldBase = 61, }, + req = { level = 48, int = 101, }, +} +itemBases["Necromancer Circlet"] = { + type = "Helmet", + armour = { energyShieldBase = 68, }, + req = { level = 54, int = 112, }, +} +itemBases["Solaris Circlet"] = { + type = "Helmet", + armour = { energyShieldBase = 75, }, + req = { level = 59, int = 122, }, +} +itemBases["Mind Cage"] = { + type = "Helmet", + armour = { energyShieldBase = 91, }, + req = { level = 65, int = 138, }, +} +itemBases["Hubris Circlet"] = { + type = "Helmet", + armour = { energyShieldBase = 100, }, + req = { level = 69, int = 154, }, +} + + +itemBases["Battered Helm"] = { + type = "Helmet", + armour = { armourBase = 11, evasionBase = 11, }, + req = { }, +} +itemBases["Sallet"] = { + type = "Helmet", + armour = { armourBase = 32, evasionBase = 32, }, + req = { level = 13, str = 18, dex = 18, }, +} +itemBases["Visored Sallet"] = { + type = "Helmet", + armour = { armourBase = 55, evasionBase = 55, }, + req = { level = 23, str = 28, dex = 28, }, +} +itemBases["Gilded Sallet"] = { + type = "Helmet", + armour = { armourBase = 78, evasionBase = 78, }, + req = { level = 33, str = 38, dex = 38, }, +} +itemBases["Secutor Helm"] = { + type = "Helmet", + armour = { armourBase = 85, evasionBase = 85, }, + req = { level = 36, str = 42, dex = 42, }, +} +itemBases["Fencer Helm"] = { + type = "Helmet", + armour = { armourBase = 102, evasionBase = 102, }, + req = { level = 43, str = 49, dex = 49, }, +} +itemBases["Lacquered Helmet"] = { + type = "Helmet", + armour = { armourBase = 120, evasionBase = 120, }, + req = { level = 51, str = 57, dex = 57, }, +} +itemBases["Fluted Bascinet"] = { + type = "Helmet", + armour = { armourBase = 139, evasionBase = 139, }, + req = { level = 58, str = 64, dex = 64, }, +} +itemBases["Pig-Faced Bascinet"] = { + type = "Helmet", + armour = { armourBase = 199, evasionBase = 139, }, + req = { level = 63, str = 85, dex = 62, }, +} +itemBases["Nightmare Bascinet"] = { + type = "Helmet", + armour = { armourBase = 141, evasionBase = 203, }, + req = { level = 67, str = 62, dex = 85, }, +} + + +itemBases["Rusted Coif"] = { + type = "Helmet", + armour = { armourBase = 14, energyShieldBase = 5, }, + req = { level = 5, }, +} +itemBases["Soldier Helmet"] = { + type = "Helmet", + armour = { armourBase = 30, energyShieldBase = 10, }, + req = { level = 12, str = 16, int = 16, }, +} +itemBases["Great Helmet"] = { + type = "Helmet", + armour = { armourBase = 53, energyShieldBase = 16, }, + req = { level = 22, str = 27, int = 27, }, +} +itemBases["Crusader Helmet"] = { + type = "Helmet", + armour = { armourBase = 74, energyShieldBase = 22, }, + req = { level = 31, str = 36, int = 36, }, +} +itemBases["Aventail Helmet"] = { + type = "Helmet", + armour = { armourBase = 88, energyShieldBase = 26, }, + req = { level = 37, str = 42, int = 42, }, +} +itemBases["Zealot Helmet"] = { + type = "Helmet", + armour = { armourBase = 104, energyShieldBase = 31, }, + req = { level = 44, str = 50, int = 50, }, +} +itemBases["Great Crown"] = { + type = "Helmet", + armour = { armourBase = 125, energyShieldBase = 37, }, + req = { level = 53, str = 59, int = 59, }, +} +itemBases["Magistrate Crown"] = { + type = "Helmet", + armour = { armourBase = 139, energyShieldBase = 41, }, + req = { level = 58, str = 64, int = 64, }, +} +itemBases["Prophet Crown"] = { + type = "Helmet", + armour = { armourBase = 195, energyShieldBase = 40, }, + req = { level = 63, str = 85, int = 62, }, +} +itemBases["Praetor Crown"] = { + type = "Helmet", + armour = { armourBase = 140, energyShieldBase = 63, }, + req = { level = 68, str = 62, int = 91, }, +} + + +itemBases["Scare Mask"] = { + type = "Helmet", + armour = { evasionBase = 11, energyShieldBase = 4, }, + req = { }, +} +itemBases["Plague Mask"] = { + type = "Helmet", + armour = { evasionBase = 25, energyShieldBase = 8, }, + req = { level = 10, dex = 14, int = 14, }, +} +itemBases["Iron Mask"] = { + type = "Helmet", + armour = { evasionBase = 41, energyShieldBase = 13, }, + req = { level = 17, dex = 21, int = 21, }, +} +itemBases["Festival Mask"] = { + type = "Helmet", + armour = { evasionBase = 67, energyShieldBase = 20, }, + req = { level = 28, dex = 33, int = 33, }, +} +itemBases["Golden Mask"] = { + type = "Helmet", + armour = { evasionBase = 83, energyShieldBase = 25, }, + req = { level = 35, dex = 40, int = 40, }, +} +itemBases["Raven Mask"] = { + type = "Helmet", + armour = { evasionBase = 90, energyShieldBase = 27, }, + req = { level = 38, dex = 44, int = 44, }, +} +itemBases["Callous Mask"] = { + type = "Helmet", + armour = { evasionBase = 106, energyShieldBase = 31, }, + req = { level = 45, dex = 51, int = 51, }, +} +itemBases["Regicide Mask"] = { + type = "Helmet", + armour = { evasionBase = 122, energyShieldBase = 36, }, + req = { level = 52, dex = 58, int = 58, }, +} +itemBases["Harlequin Mask"] = { + type = "Helmet", + armour = { evasionBase = 137, energyShieldBase = 40, }, + req = { level = 57, dex = 64, int = 64, }, +} +itemBases["Vaal Mask"] = { + type = "Helmet", + armour = { evasionBase = 180, energyShieldBase = 47, }, + req = { level = 62, dex = 79, int = 72, }, +} +itemBases["Deicide Mask"] = { + type = "Helmet", + armour = { evasionBase = 166, energyShieldBase = 59, }, + req = { level = 67, dex = 73, int = 88, }, +} diff --git a/Items/mace.lua b/Items/mace.lua new file mode 100644 index 00000000..6c1d0b6d --- /dev/null +++ b/Items/mace.lua @@ -0,0 +1,438 @@ +local itemBases = ... + +itemBases["Driftwood Club"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 5, physicalMax = 7, critChanceBase = 5, attackRateBase = 1.45, }, + req = { str = 14, }, +} +itemBases["Tribal Club"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 7, physicalMax = 12, critChanceBase = 5, attackRateBase = 1.35, }, + req = { level = 5, str = 26, }, +} +itemBases["Spiked Club"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 11, physicalMax = 14, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 10, str = 41, }, +} +itemBases["Stone Hammer"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 14, physicalMax = 27, critChanceBase = 5, attackRateBase = 1.15, }, + req = { level = 15, str = 56, }, +} +itemBases["War Hammer"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 11, physicalMax = 26, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 20, str = 71, }, +} +itemBases["Bladed Mace"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 18, physicalMax = 30, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 24, str = 83, }, +} +itemBases["Ceremonial Mace"] = { + type = "One Handed Mace", + implicit = "40% increased Stun Duration on enemies", + weapon = { physicalMin = 26, physicalMax = 33, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 28, str = 95, }, +} +itemBases["Dream Mace"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 17, physicalMax = 35, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 32, str = 107, }, +} +itemBases["Wyrm Mace"] = { + type = "One Handed Mace", + implicit = "4% increased Attack Speed", + weapon = { physicalMin = 23, physicalMax = 35, critChanceBase = 5, attackRateBase = 1.35, }, + req = { level = 34, str = 118, }, +} +itemBases["Petrified Club"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 25, physicalMax = 41, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 35, str = 116, }, +} +itemBases["Barbed Club"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 27, physicalMax = 34, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 38, str = 125, }, +} +itemBases["Rock Breaker"] = { + type = "One Handed Mace", + implicit = "40% increased Stun Duration on enemies", + weapon = { physicalMin = 30, physicalMax = 55, critChanceBase = 5, attackRateBase = 1.15, }, + req = { level = 41, str = 134, }, +} +itemBases["Battle Hammer"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 20, physicalMax = 48, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 44, str = 143, }, +} +itemBases["Flanged Mace"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 30, physicalMax = 50, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 47, str = 152, }, +} +itemBases["Ornate Mace"] = { + type = "One Handed Mace", + implicit = "40% increased Stun Duration on enemies", + weapon = { physicalMin = 42, physicalMax = 53, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 50, str = 161, }, +} +itemBases["Phantom Mace"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 26, physicalMax = 54, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 53, str = 170, }, +} +itemBases["Dragon Mace"] = { + type = "One Handed Mace", + implicit = "4% increased Attack Speed", + weapon = { physicalMin = 35, physicalMax = 53, critChanceBase = 5, attackRateBase = 1.35, }, + req = { level = 55, str = 184, }, +} +itemBases["Ancestral Club"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 37, physicalMax = 62, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 56, str = 179, }, +} +itemBases["Tenderizer"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 38, physicalMax = 49, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 58, str = 185, }, +} +itemBases["Gavel"] = { + type = "One Handed Mace", + implicit = "40% increased Stun Duration on enemies", + weapon = { physicalMin = 42, physicalMax = 77, critChanceBase = 5, attackRateBase = 1.15, }, + req = { level = 60, str = 212, }, +} +itemBases["Legion Hammer"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 27, physicalMax = 63, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 62, str = 212, }, +} +itemBases["Pernarch"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 37, physicalMax = 62, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 64, str = 212, }, +} +itemBases["Auric Mace"] = { + type = "One Handed Mace", + implicit = "40% increased Stun Duration on enemies", + weapon = { physicalMin = 49, physicalMax = 63, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 66, str = 212, }, +} +itemBases["Nightmare Mace"] = { + type = "One Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 29, physicalMax = 61, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 68, str = 212, }, +} +itemBases["Behemoth Mace"] = { + type = "One Handed Mace", + implicit = "6% increased Attack Speed", + weapon = { physicalMin = 38, physicalMax = 57, critChanceBase = 5, attackRateBase = 1.35, }, + req = { level = 70, str = 220, }, +} + + +itemBases["Driftwood Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 5, physicalMax = 7, critChanceBase = 6, attackRateBase = 1.4, }, + req = { level = 1, str = 8, int = 8, }, +} +itemBases["Darkwood Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 7, physicalMax = 10, critChanceBase = 6, attackRateBase = 1.5, }, + req = { level = 5, str = 14, int = 14, }, +} +itemBases["Bronze Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 10, physicalMax = 19, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 10, str = 22, int = 22, }, +} +itemBases["Quartz Sceptre"] = { + type = "One Handed Mace", + implicit = "20% increased Elemental Damage", + weapon = { physicalMin = 14, physicalMax = 21, critChanceBase = 7, attackRateBase = 1.25, }, + req = { level = 15, str = 25, int = 35, }, +} +itemBases["Iron Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 18, physicalMax = 27, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 20, str = 38, int = 38, }, +} +itemBases["Ochre Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 15, physicalMax = 28, critChanceBase = 6, attackRateBase = 1.4, }, + req = { level = 24, str = 44, int = 44, }, +} +itemBases["Ritual Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 18, physicalMax = 41, critChanceBase = 6, attackRateBase = 1.2, }, + req = { level = 28, str = 51, int = 51, }, +} +itemBases["Shadow Sceptre"] = { + type = "One Handed Mace", + implicit = "15% increased Elemental Damage", + weapon = { physicalMin = 25, physicalMax = 37, critChanceBase = 6.5, attackRateBase = 1.25, }, + req = { level = 32, str = 52, int = 62, }, +} +itemBases["Grinning Fetish"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 21, physicalMax = 32, critChanceBase = 6, attackRateBase = 1.5, }, + req = { level = 35, str = 62, int = 62, }, +} +itemBases["Horned Sceptre"] = { + type = "One Handed Mace", + implicit = "Damage Penetrates 1% Elemental Resistances", + weapon = { physicalMin = 22, physicalMax = 42, critChanceBase = 6, attackRateBase = 1.3, }, + req = { level = 36, str = 66, int = 66, }, +} +itemBases["Sekhem"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 25, physicalMax = 46, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 38, str = 67, int = 67, }, +} +itemBases["Crystal Sceptre"] = { + type = "One Handed Mace", + implicit = "20% increased Elemental Damage", + weapon = { physicalMin = 29, physicalMax = 43, critChanceBase = 7, attackRateBase = 1.25, }, + req = { level = 41, str = 59, int = 85, }, +} +itemBases["Lead Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 32, physicalMax = 48, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 44, str = 77, int = 77, }, +} +itemBases["Blood Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 25, physicalMax = 47, critChanceBase = 6, attackRateBase = 1.4, }, + req = { level = 47, str = 81, int = 81, }, +} +itemBases["Royal Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 29, physicalMax = 67, critChanceBase = 6, attackRateBase = 1.2, }, + req = { level = 50, str = 86, int = 86, }, +} +itemBases["Abyssal Sceptre"] = { + type = "One Handed Mace", + implicit = "15% increased Elemental Damage", + weapon = { physicalMin = 38, physicalMax = 57, critChanceBase = 6.5, attackRateBase = 1.25, }, + req = { level = 53, str = 83, int = 99, }, +} +itemBases["Stag Sceptre"] = { + type = "One Handed Mace", + implicit = "Damage Penetrates 1% Elemental Resistances", + weapon = { physicalMin = 32, physicalMax = 60, critChanceBase = 6, attackRateBase = 1.3, }, + req = { level = 55, str = 98, int = 98, }, +} +itemBases["Karui Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 32, physicalMax = 47, critChanceBase = 6, attackRateBase = 1.5, }, + req = { level = 56, str = 96, int = 96, }, +} +itemBases["Tyrant's Sekhem"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 36, physicalMax = 67, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 58, str = 99, int = 99, }, +} +itemBases["Opal Sceptre"] = { + type = "One Handed Mace", + implicit = "20% increased Elemental Damage", + weapon = { physicalMin = 40, physicalMax = 60, critChanceBase = 7, attackRateBase = 1.25, }, + req = { level = 60, str = 95, int = 131, }, +} +itemBases["Platinum Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 42, physicalMax = 63, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 62, str = 113, int = 113, }, +} +itemBases["Vaal Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 31, physicalMax = 58, critChanceBase = 6, attackRateBase = 1.4, }, + req = { level = 64, str = 113, int = 113, }, +} +itemBases["Carnal Sceptre"] = { + type = "One Handed Mace", + implicit = "10% increased Elemental Damage", + weapon = { physicalMin = 34, physicalMax = 78, critChanceBase = 6, attackRateBase = 1.2, }, + req = { level = 66, str = 113, int = 113, }, +} +itemBases["Void Sceptre"] = { + type = "One Handed Mace", + implicit = "15% increased Elemental Damage", + weapon = { physicalMin = 42, physicalMax = 63, critChanceBase = 6.5, attackRateBase = 1.25, }, + req = { level = 68, str = 104, int = 122, }, +} +itemBases["Sambar Sceptre"] = { + type = "One Handed Mace", + implicit = "Damage Penetrates 2% Elemental Resistances", + weapon = { physicalMin = 35, physicalMax = 65, critChanceBase = 6, attackRateBase = 1.3, }, + req = { level = 70, str = 121, int = 112, }, +} + + +itemBases["Driftwood Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 9, physicalMax = 13, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 3, str = 20, }, +} +itemBases["Tribal Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 15, physicalMax = 23, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 8, str = 35, }, +} +itemBases["Mallet"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 15, physicalMax = 30, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 12, str = 47, }, +} +itemBases["Sledgehammer"] = { + type = "Two Handed Mace", + implicit = "40% increased Stun Duration on enemies", + weapon = { physicalMin = 21, physicalMax = 32, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 17, str = 62, }, +} +itemBases["Jagged Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 24, physicalMax = 45, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 22, str = 77, }, +} +itemBases["Brass Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 34, physicalMax = 51, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 27, str = 92, }, +} +itemBases["Fright Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 39, physicalMax = 53, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 32, str = 107, }, +} +itemBases["Morning Star"] = { + type = "Two Handed Mace", + implicit = "4% increased Radius of Area Skills", + weapon = { physicalMin = 39, physicalMax = 58, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 34, str = 118, }, +} +itemBases["Totemic Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 49, physicalMax = 73, critChanceBase = 5, attackRateBase = 1.1, }, + req = { level = 36, str = 119, }, +} +itemBases["Great Mallet"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 37, physicalMax = 76, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 40, str = 131, }, +} +itemBases["Steelhead"] = { + type = "Two Handed Mace", + implicit = "40% increased Stun Duration on enemies", + weapon = { physicalMin = 47, physicalMax = 70, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 44, str = 143, }, +} +itemBases["Spiny Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 47, physicalMax = 88, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 48, str = 155, }, +} +itemBases["Plated Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 62, physicalMax = 92, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 51, str = 164, }, +} +itemBases["Dread Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 66, physicalMax = 89, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 54, str = 173, }, +} +itemBases["Solar Maul"] = { + type = "Two Handed Mace", + implicit = "4% increased Radius of Area Skills", + weapon = { physicalMin = 64, physicalMax = 97, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 56, str = 187, }, +} +itemBases["Karui Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 79, physicalMax = 118, critChanceBase = 5, attackRateBase = 1.1, }, + req = { level = 57, str = 182, }, +} +itemBases["Colossus Mallet"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 57, physicalMax = 118, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 59, str = 188, }, +} +itemBases["Piledriver"] = { + type = "Two Handed Mace", + implicit = "40% increased Stun Duration on enemies", + weapon = { physicalMin = 67, physicalMax = 100, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 61, str = 212, }, +} +itemBases["Meatgrinder"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 63, physicalMax = 117, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 63, str = 212, }, +} +itemBases["Imperial Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 74, physicalMax = 111, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 65, str = 212, }, +} +itemBases["Terror Maul"] = { + type = "Two Handed Mace", + implicit = "20% increased Stun Duration on enemies", + weapon = { physicalMin = 75, physicalMax = 102, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 67, str = 212, }, +} +itemBases["Coronal Maul"] = { + type = "Two Handed Mace", + implicit = "6% increased Radius of Area Skills", + weapon = { physicalMin = 74, physicalMax = 110, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 69, str = 220, }, +} diff --git a/Items/misc.lua b/Items/misc.lua new file mode 100644 index 00000000..94a2797e --- /dev/null +++ b/Items/misc.lua @@ -0,0 +1,332 @@ +local itemBases = ... + +itemBases["Paua Amulet"] = { + type = "Amulet", + implicit = "(20 to 30)% increased Mana Regeneration Rate", + req = { }, +} +itemBases["Coral Amulet"] = { + type = "Amulet", + implicit = "(2 to 4) Life Regenerated per Second", + req = { }, +} +itemBases["Amber Amulet"] = { + type = "Amulet", + implicit = "+(20 to 30) Strength", + req = { level = 5, }, +} +itemBases["Jade Amulet"] = { + type = "Amulet", + implicit = "+(20 to 30) Dexterity", + req = { level = 5, }, +} +itemBases["Lapis Amulet"] = { + type = "Amulet", + implicit = "+(20 to 30) Intelligence", + req = { level = 5, }, +} +itemBases["Gold Amulet"] = { + type = "Amulet", + implicit = "(12 to 20)% increased Rarity of Items found", + req = { level = 8, }, +} +itemBases["Onyx Amulet"] = { + type = "Amulet", + implicit = "+(10 to 16) to all Attributes", + req = { level = 20, }, +} +itemBases["Agate Amulet"] = { + type = "Amulet", + implicit = "+(16 to 24) to Strength and Intelligence", + req = { level = 16, }, +} +itemBases["Turquoise Amulet"] = { + type = "Amulet", + implicit = "+(16 to 24) to Dexterity and Intelligence", + req = { level = 16, }, +} +itemBases["Citrine Amulet"] = { + type = "Amulet", + implicit = "+(16 to 24) to Strength and Dexterity", + req = { level = 16, }, +} +itemBases["Ruby Amulet"] = { + type = "Amulet", + implicit = "+(20 to 30)% to Fire Resistance", + req = { level = 35, }, +} + + +itemBases["Rustic Sash"] = { + type = "Belt", + implicit = "(12 to 24)% increased Physical Damage", + req = { }, +} +itemBases["Chain Belt"] = { + type = "Belt", + implicit = "+(9 to 20) to maximum Energy Shield", + req = { }, +} +itemBases["Leather Belt"] = { + type = "Belt", + implicit = "+(25 to 40) to maximum Life", + req = { level = 8, }, +} +itemBases["Heavy Belt"] = { + type = "Belt", + implicit = "+(25 to 35) to Strength", + req = { level = 8, }, +} +itemBases["Studded Belt"] = { + type = "Belt", + implicit = "(20 to 30)% increased Stun Duration on enemies", + req = { level = 16, }, +} +itemBases["Cloth Belt"] = { + type = "Belt", + implicit = "(15 to 25)% increased Stun Recovery", + req = { level = 16, }, +} + + +itemBases["Serrated Arrow Quiver"] = { + type = "Quiver", + implicit = "Adds 1-4 Physical Damage to Attacks with Bows", + req = { level = 5, }, +} +itemBases["Two-Point Arrow Quiver"] = { + type = "Quiver", + implicit = "(20 to 30)% increased Accuracy Rating", + req = { level = 4, }, +} +itemBases["Sharktooth Arrow Quiver"] = { + type = "Quiver", + implicit = "+(3 to 4) Life gained for each Enemy hit by your Attacks", + req = { level = 10, }, +} +itemBases["Blunt Arrow Quiver"] = { + type = "Quiver", + implicit = "(25 to 35)% increased Stun Duration on Enemies", + req = { level = 16, }, +} +itemBases["Fire Arrow Quiver"] = { + type = "Quiver", + implicit = "Adds 4-8 Fire Damage to Attacks with Bows", + req = { level = 22, }, +} +itemBases["Broadhead Arrow Quiver"] = { + type = "Quiver", + implicit = "Adds 6-12 Physical Damage to Attacks with Bows", + req = { level = 28, }, +} +itemBases["Penetrating Arrow Quiver"] = { + type = "Quiver", + implicit = "10% chance of Arrows Piercing", + req = { level = 36, }, +} +itemBases["Spike-Point Arrow Quiver"] = { + type = "Quiver", + implicit = "(20 to 30)% increased Global Critical Strike Chance", + req = { level = 45, }, +} + + +itemBases["Iron Ring"] = { + type = "Ring", + implicit = "Adds 1-4 Physical Damage to Attacks", + req = { }, +} +itemBases["Coral Ring"] = { + type = "Ring", + implicit = "+(20 to 30) to Maximum Life", + req = { }, +} +itemBases["Paua Ring"] = { + type = "Ring", + implicit = "+(20 to 25) to Maximum Mana", + req = { }, +} +itemBases["Gold Ring"] = { + type = "Ring", + implicit = "(6 to 15)% increased Rarity of Items found", + req = { level = 20, }, +} +itemBases["Ruby Ring"] = { + type = "Ring", + implicit = "+(20 to 30)% to Fire Resistance", + req = { level = 16, }, +} +itemBases["Sapphire Ring"] = { + type = "Ring", + implicit = "+(20 to 30)% to Cold Resistance", + req = { level = 8, }, +} +itemBases["Topaz Ring"] = { + type = "Ring", + implicit = "+(20 to 30)% to Lightning Resistance", + req = { level = 12, }, +} +itemBases["Diamond Ring"] = { + type = "Ring", + implicit = "(20 to 30)% increased Global Critical Strike Chance", + req = { level = 20, }, +} +itemBases["Moonstone Ring"] = { + type = "Ring", + implicit = "+(15 to 25) to maximum Energy Shield", + req = { level = 20, }, +} +itemBases["Prismatic Ring"] = { + type = "Ring", + implicit = "+(8 to 10)% to all Elemental Resistances", + req = { level = 30, }, +} +itemBases["Amethyst Ring"] = { + type = "Ring", + implicit = "+(9 to 13)% to Chaos Resistance", + req = { level = 30, }, +} +itemBases["Two-Stone Ring"] = { + type = "Ring", + implicit = "+(12 to 16)% to Fire and Cold Resistances", + req = { level = 20, }, +} +itemBases["Two-Stone Ring"] = { + type = "Ring", + implicit = "+(12 to 16)% to Cold and Lightning Resistances", + req = { level = 20, }, +} +itemBases["Two-Stone Ring"] = { + type = "Ring", + implicit = "+(12 to 16)% to Fire and Lightning Resistances", + req = { level = 20, }, +} +itemBases["Unset Ring"] = { + type = "Ring", + implicit = "Has 1 Socket", + req = { level = 5, }, +} + + +itemBases["Crimson Jewel"] = { + type = "Jewel", +} +itemBases["Viridian Jewel"] = { + type = "Jewel", +} +itemBases["Cobalt Jewel"] = { + type = "Jewel", +} + + +itemBases["Ashscale Talisman"] = { + type = "Amulet", + implicit = "(20 to 30)% increased Fire Damage", +} +itemBases["Black Maw Talisman"] = { + type = "Amulet", + implicit = "Has 1 Socket", +} +itemBases["Bonespire Talisman"] = { + type = "Amulet", + implicit = "(20 to 30)% increased maximum Mana", +} +itemBases["Breakrib Talisman"] = { + type = "Amulet", + implicit = "(20 to 30)% increased Physical Damage", +} +itemBases["Chrysalis Talisman"] = { + type = "Amulet", + implicit = "(20 to 30)% increased Spell Damage", +} +itemBases["Deadhand Talisman"] = { + type = "Amulet", + implicit = "(19 to 31)% increased Chaos Damage", +} +itemBases["Deep One Talisman"] = { + type = "Amulet", + implicit = "(20 to 30)% increased Cold Damage", +} +itemBases["Lone Antler Talisman"] = { + type = "Amulet", + implicit = "(20 to 30)% increased Lightning Damage", +} +itemBases["Mandible Talisman"] = { + type = "Amulet", + implicit = "(6 to 10)% increased Attack and Cast Speed", +} +itemBases["Undying Flesh Talisman"] = { + type = "Amulet", + implicit = "+1 to maximum number of Zombies", +} +itemBases["Writhing Talisman"] = { + type = "Amulet", + implicit = "(20 to 30)% increased Attack Damage", +} +itemBases["Avian Twins Talisman"] = { + type = "Amulet", + implicit = "", +} +itemBases["Clutching Talisman"] = { + type = "Amulet", + implicit = "(15 to 25)% increased Global Defences", +} +itemBases["Fangjaw Talisman"] = { + type = "Amulet", + implicit = "(8 to 12)% increased maximum Life", +} +itemBases["Hexclaw Talisman"] = { + type = "Amulet", + implicit = "(40 to 50)% increased Global Critical Strike Chance", +} +itemBases["Horned Talisman"] = { + type = "Amulet", + implicit = "(25 to 35)% chance of Projectiles Piercing", +} +itemBases["Primal Skull Talisman"] = { + type = "Amulet", + implicit = "2% of Life Regenerated per Second", +} +itemBases["Splitnewt Talisman"] = { + type = "Amulet", + implicit = "(4 to 6)% chance to Freeze, Shock and Ignite", +} +itemBases["Wereclaw Talisman"] = { + type = "Amulet", + implicit = "+(16 to 24)% to Global Critical Strike Multiplier", +} +itemBases["Longtooth Talisman"] = { + type = "Amulet", + implicit = "(4 to 6)% additional Physical Damage Reduction", +} +itemBases["Monkey Paw Talisman"] = { + type = "Amulet", + implicit = "", +} +itemBases["Monkey Twins Talisman"] = { + type = "Amulet", + implicit = "(5 to 8)% increased Radius of Area Skills", +} +itemBases["Rotfeather Talisman"] = { + type = "Amulet", + implicit = "(25 to 35)% increased Damage", +} +itemBases["Spinefuse Talisman"] = { + type = "Amulet", + implicit = "(6 to 10)% increased Quantity of Items found", +} +itemBases["Three Hands Talisman"] = { + type = "Amulet", + implicit = "Gain (6 to 12)% of Physical Damage as Extra Damage of a random Element", +} +itemBases["Three Rat Talisman"] = { + type = "Amulet", + implicit = "(12 to 16)% increased Attributes", +} +itemBases["Greatwolf Talisman"] = { + type = "Amulet", + implicit = "", +} + + + diff --git a/Items/shield.lua b/Items/shield.lua new file mode 100644 index 00000000..863c4630 --- /dev/null +++ b/Items/shield.lua @@ -0,0 +1,498 @@ +local itemBases = ... + +itemBases["Splintered Tower Shield"] = { + type = "Shield", + armour = { blockChance = 24, armourBase = 8, }, + req = { }, +} +itemBases["Corroded Tower Shield"] = { + type = "Shield", + armour = { blockChance = 23, armourBase = 40, }, + req = { level = 5, str = 20, }, +} +itemBases["Rawhide Tower Shield"] = { + type = "Shield", + armour = { blockChance = 26, armourBase = 46, }, + req = { level = 11, str = 33, }, +} +itemBases["Cedar Tower Shield"] = { + type = "Shield", + armour = { blockChance = 25, armourBase = 94, }, + req = { level = 17, str = 46, }, +} +itemBases["Copper Tower Shield"] = { + type = "Shield", + armour = { blockChance = 24, armourBase = 166, }, + req = { level = 24, str = 62, }, +} +itemBases["Reinforced Tower Shield"] = { + type = "Shield", + armour = { blockChance = 23, armourBase = 249, }, + req = { level = 30, str = 76, }, +} +itemBases["Painted Tower Shield"] = { + type = "Shield", + armour = { blockChance = 25, armourBase = 189, }, + req = { level = 35, str = 87, }, +} +itemBases["Buckskin Tower Shield"] = { + type = "Shield", + armour = { blockChance = 26, armourBase = 154, }, + req = { level = 39, str = 96, }, +} +itemBases["Mahogany Tower Shield"] = { + type = "Shield", + armour = { blockChance = 25, armourBase = 231, }, + req = { level = 43, str = 105, }, +} +itemBases["Bronze Tower Shield"] = { + type = "Shield", + armour = { blockChance = 24, armourBase = 319, }, + req = { level = 47, str = 114, }, +} +itemBases["Girded Tower Shield"] = { + type = "Shield", + armour = { blockChance = 23, armourBase = 418, }, + req = { level = 51, str = 123, }, +} +itemBases["Crested Tower Shield"] = { + type = "Shield", + armour = { blockChance = 25, armourBase = 294, }, + req = { level = 55, str = 132, }, +} +itemBases["Shagreen Tower Shield"] = { + type = "Shield", + armour = { blockChance = 26, armourBase = 227, }, + req = { level = 58, str = 139, }, +} +itemBases["Ebony Tower Shield"] = { + type = "Shield", + armour = { blockChance = 25, armourBase = 358, }, + req = { level = 61, str = 159, }, +} +itemBases["Ezomyte Tower Shield"] = { + type = "Shield", + armour = { blockChance = 24, armourBase = 454, }, + req = { level = 64, str = 159, }, +} +itemBases["Colossal Tower Shield"] = { + type = "Shield", + armour = { blockChance = 23, armourBase = 550, }, + req = { level = 67, str = 159, }, +} +itemBases["Pinnacle Tower Shield"] = { + type = "Shield", + armour = { blockChance = 25, armourBase = 406, }, + req = { level = 70, str = 159, }, +} + + +itemBases["Goathide Buckler"] = { + type = "Shield", + armour = { blockChance = 25, evasionBase = 10, }, + req = { }, +} +itemBases["Pine Buckler"] = { + type = "Shield", + armour = { blockChance = 26, evasionBase = 38, }, + req = { level = 8, dex = 26, }, +} +itemBases["Painted Buckler"] = { + type = "Shield", + armour = { blockChance = 24, evasionBase = 95, }, + req = { level = 16, dex = 44, }, +} +itemBases["Hammered Buckler"] = { + type = "Shield", + armour = { blockChance = 27, evasionBase = 84, }, + req = { level = 23, dex = 60, }, +} +itemBases["War Buckler"] = { + type = "Shield", + armour = { blockChance = 26, evasionBase = 126, }, + req = { level = 29, dex = 74, }, +} +itemBases["Gilded Buckler"] = { + type = "Shield", + armour = { blockChance = 25, evasionBase = 171, }, + req = { level = 34, dex = 85, }, +} +itemBases["Oak Buckler"] = { + type = "Shield", + armour = { blockChance = 26, evasionBase = 164, }, + req = { level = 38, dex = 94, }, +} +itemBases["Enameled Buckler"] = { + type = "Shield", + armour = { blockChance = 24, evasionBase = 241, }, + req = { level = 42, dex = 103, }, +} +itemBases["Corrugated Buckler"] = { + type = "Shield", + armour = { blockChance = 27, evasionBase = 164, }, + req = { level = 46, dex = 112, }, +} +itemBases["Battle Buckler"] = { + type = "Shield", + armour = { blockChance = 26, evasionBase = 214, }, + req = { level = 50, dex = 121, }, +} +itemBases["Golden Buckler"] = { + type = "Shield", + armour = { blockChance = 25, evasionBase = 269, }, + req = { level = 54, dex = 130, }, +} +itemBases["Ironwood Buckler"] = { + type = "Shield", + armour = { blockChance = 26, evasionBase = 243, }, + req = { level = 57, dex = 136, }, +} +itemBases["Lacquered Buckler"] = { + type = "Shield", + armour = { blockChance = 24, evasionBase = 382, }, + req = { level = 60, dex = 159, }, +} +itemBases["Vaal Buckler"] = { + type = "Shield", + armour = { blockChance = 27, evasionBase = 239, }, + req = { level = 63, dex = 159, }, +} +itemBases["Crusader Buckler"] = { + type = "Shield", + armour = { blockChance = 26, evasionBase = 287, }, + req = { level = 66, dex = 159, }, +} +itemBases["Imperial Buckler"] = { + type = "Shield", + armour = { blockChance = 25, evasionBase = 335, }, + req = { level = 69, dex = 159, }, +} + + +itemBases["Twig Spirit Shield"] = { + type = "Shield", + implicit = "10% increased Spell Damage", + armour = { blockChance = 22, energyShieldBase = 5, }, + req = { int = 15, }, +} +itemBases["Yew Spirit Shield"] = { + type = "Shield", + implicit = "5% increased Spell Damage", + armour = { blockChance = 24, energyShieldBase = 11, }, + req = { level = 9, int = 28, }, +} +itemBases["Bone Spirit Shield"] = { + type = "Shield", + implicit = "15% increased Spell Damage", + armour = { blockChance = 22, energyShieldBase = 17, }, + req = { level = 15, int = 42, }, +} +itemBases["Tarnished Spirit Shield"] = { + type = "Shield", + implicit = "5% increased Spell Damage", + armour = { blockChance = 24, energyShieldBase = 25, }, + req = { level = 23, int = 60, }, +} +itemBases["Jingling Spirit Shield"] = { + type = "Shield", + implicit = "10% increased Spell Damage", + armour = { blockChance = 23, energyShieldBase = 30, }, + req = { level = 28, int = 71, }, +} +itemBases["Brass Spirit Shield"] = { + type = "Shield", + armour = { blockChance = 25, energyShieldBase = 43, }, + req = { level = 33, int = 82, }, +} +itemBases["Walnut Spirit Shield"] = { + type = "Shield", + implicit = "5% increased Spell Damage", + armour = { blockChance = 24, energyShieldBase = 39, }, + req = { level = 37, int = 92, }, +} +itemBases["Ivory Spirit Shield"] = { + type = "Shield", + implicit = "15% increased Spell Damage", + armour = { blockChance = 22, energyShieldBase = 43, }, + req = { level = 41, int = 100, }, +} +itemBases["Ancient Spirit Shield"] = { + type = "Shield", + implicit = "5% increased Spell Damage", + armour = { blockChance = 24, energyShieldBase = 47, }, + req = { level = 45, int = 110, }, +} +itemBases["Chiming Spirit Shield"] = { + type = "Shield", + implicit = "10% increased Spell Damage", + armour = { blockChance = 23, energyShieldBase = 51, }, + req = { level = 49, int = 118, }, +} +itemBases["Thorium Spirit Shield"] = { + type = "Shield", + armour = { blockChance = 25, energyShieldBase = 67, }, + req = { level = 53, int = 128, }, +} +itemBases["Lacewood Spirit Shield"] = { + type = "Shield", + implicit = "5% increased Spell Damage", + armour = { blockChance = 24, energyShieldBase = 58, }, + req = { level = 56, int = 134, }, +} +itemBases["Fossilised Spirit Shield"] = { + type = "Shield", + implicit = "15% increased Spell Damage", + armour = { blockChance = 22, energyShieldBase = 61, }, + req = { level = 59, int = 141, }, +} +itemBases["Vaal Spirit Shield"] = { + type = "Shield", + implicit = "5% increased Spell Damage", + armour = { blockChance = 24, energyShieldBase = 70, }, + req = { level = 62, int = 159, }, +} +itemBases["Harmonic Spirit Shield"] = { + type = "Shield", + implicit = "10% increased Spell Damage", + armour = { blockChance = 23, energyShieldBase = 72, }, + req = { level = 65, int = 159, }, +} +itemBases["Titanium Spirit Shield"] = { + type = "Shield", + armour = { blockChance = 25, energyShieldBase = 84, }, + req = { level = 68, int = 159, }, +} + + +itemBases["Rotted Round Shield"] = { + type = "Shield", + implicit = "60% increased Block Recovery", + armour = { blockChance = 23, armourBase = 11, evasionBase = 11, }, + req = { level = 5, }, +} +itemBases["Fir Round Shield"] = { + type = "Shield", + implicit = "180% increased Block Recovery", + armour = { blockChance = 23, armourBase = 25, evasionBase = 25, }, + req = { level = 12, str = 19, dex = 19, }, +} +itemBases["Studded Round Shield"] = { + type = "Shield", + implicit = "60% increased Block Recovery", + armour = { blockChance = 26, armourBase = 40, evasionBase = 40, }, + req = { level = 20, str = 28, dex = 28, }, +} +itemBases["Scarlet Round Shield"] = { + type = "Shield", + armour = { blockChance = 25, armourBase = 75, evasionBase = 75, }, + req = { level = 27, str = 37, dex = 37, }, +} +itemBases["Splendid Round Shield"] = { + type = "Shield", + implicit = "120% increased Block Recovery", + armour = { blockChance = 24, armourBase = 65, evasionBase = 65, }, + req = { level = 33, str = 44, dex = 44, }, +} +itemBases["Maple Round Shield"] = { + type = "Shield", + implicit = "180% increased Block Recovery", + armour = { blockChance = 23, armourBase = 77, evasionBase = 77, }, + req = { level = 39, str = 52, dex = 52, }, +} +itemBases["Spiked Round Shield"] = { + type = "Shield", + implicit = "60% increased Block Recovery", + armour = { blockChance = 26, armourBase = 88, evasionBase = 88, }, + req = { level = 45, str = 58, dex = 58, }, +} +itemBases["Crimson Round Shield"] = { + type = "Shield", + armour = { blockChance = 25, armourBase = 135, evasionBase = 135, }, + req = { level = 49, str = 64, dex = 64, }, +} +itemBases["Baroque Round Shield"] = { + type = "Shield", + implicit = "120% increased Block Recovery", + armour = { blockChance = 24, armourBase = 106, evasionBase = 106, }, + req = { level = 54, str = 70, dex = 70, }, +} +itemBases["Teak Round Shield"] = { + type = "Shield", + implicit = "180% increased Block Recovery", + armour = { blockChance = 23, armourBase = 114, evasionBase = 114, }, + req = { level = 58, str = 74, dex = 74, }, +} +itemBases["Spiny Round Shield"] = { + type = "Shield", + implicit = "60% increased Block Recovery", + armour = { blockChance = 26, armourBase = 134, evasionBase = 134, }, + req = { level = 62, str = 85, dex = 85, }, +} +itemBases["Cardinal Round Shield"] = { + type = "Shield", + armour = { blockChance = 25, armourBase = 181, evasionBase = 181, }, + req = { level = 66, str = 85, dex = 85, }, +} +itemBases["Elegant Round Shield"] = { + type = "Shield", + implicit = "120% increased Block Recovery", + armour = { blockChance = 24, armourBase = 129, evasionBase = 129, }, + req = { level = 70, str = 85, dex = 85, }, +} + + +itemBases["Plank Kite Shield"] = { + type = "Shield", + implicit = "+4% to all Elemental Resistances", + armour = { blockChance = 22, armourBase = 15, energyShieldBase = 5, }, + req = { level = 7, }, +} +itemBases["Linden Kite Shield"] = { + type = "Shield", + implicit = "+4% to all Elemental Resistances", + armour = { blockChance = 24, armourBase = 38, energyShieldBase = 12, }, + req = { level = 13, str = 20, int = 20, }, +} +itemBases["Reinforced Kite Shield"] = { + type = "Shield", + armour = { blockChance = 26, armourBase = 56, energyShieldBase = 17, }, + req = { level = 20, str = 28, int = 28, }, +} +itemBases["Layered Kite Shield"] = { + type = "Shield", + implicit = "+8% to all Elemental Resistances", + armour = { blockChance = 24, armourBase = 54, energyShieldBase = 16, }, + req = { level = 27, str = 37, int = 37, }, +} +itemBases["Ceremonial Kite Shield"] = { + type = "Shield", + implicit = "+12% to all Elemental Resistances", + armour = { blockChance = 22, armourBase = 67, energyShieldBase = 20, }, + req = { level = 34, str = 46, int = 46, }, +} +itemBases["Etched Kite Shield"] = { + type = "Shield", + implicit = "+4% to all Elemental Resistances", + armour = { blockChance = 24, armourBase = 110, energyShieldBase = 33, }, + req = { level = 40, str = 52, int = 52, }, +} +itemBases["Steel Kite Shield"] = { + type = "Shield", + armour = { blockChance = 26, armourBase = 127, energyShieldBase = 37, }, + req = { level = 46, str = 60, int = 60, }, +} +itemBases["Laminated Kite Shield"] = { + type = "Shield", + implicit = "+8% to all Elemental Resistances", + armour = { blockChance = 24, armourBase = 98, energyShieldBase = 29, }, + req = { level = 50, str = 64, int = 64, }, +} +itemBases["Angelic Kite Shield"] = { + type = "Shield", + implicit = "+12% to all Elemental Resistances", + armour = { blockChance = 22, armourBase = 108, energyShieldBase = 32, }, + req = { level = 55, str = 70, int = 70, }, +} +itemBases["Branded Kite Shield"] = { + type = "Shield", + implicit = "+4% to all Elemental Resistances", + armour = { blockChance = 24, armourBase = 162, energyShieldBase = 47, }, + req = { level = 59, str = 76, int = 76, }, +} +itemBases["Champion Kite Shield"] = { + type = "Shield", + armour = { blockChance = 26, armourBase = 187, energyShieldBase = 55, }, + req = { level = 62, str = 85, int = 85, }, +} +itemBases["Mosaic Kite Shield"] = { + type = "Shield", + implicit = "+8% to all Elemental Resistances", + armour = { blockChance = 24, armourBase = 127, energyShieldBase = 37, }, + req = { level = 65, str = 85, int = 85, }, +} +itemBases["Archon Kite Shield"] = { + type = "Shield", + implicit = "+12% to all Elemental Resistances", + armour = { blockChance = 22, armourBase = 135, energyShieldBase = 40, }, + req = { level = 68, str = 85, int = 85, }, +} + + +itemBases["Spiked Bundle"] = { + type = "Shield", + implicit = "Reflects (2 to 5) Physical Damage to Melee Attackers", + armour = { blockChance = 24, evasionBase = 11, energyShieldBase = 4, }, + req = { level = 5, }, +} +itemBases["Driftwood Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (2 to 5) Physical Damage to Melee Attackers", + armour = { blockChance = 24, evasionBase = 40, energyShieldBase = 13, }, + req = { level = 12, dex = 19, int = 19, }, +} +itemBases["Alloyed Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (5 to 12) Physical Damage to Melee Attackers", + armour = { blockChance = 25, evasionBase = 48, energyShieldBase = 15, }, + req = { level = 20, dex = 28, int = 28, }, +} +itemBases["Burnished Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (10 to 23) Physical Damage to Melee Attackers", + armour = { blockChance = 26, evasionBase = 54, energyShieldBase = 16, }, + req = { level = 27, dex = 37, int = 37, }, +} +itemBases["Ornate Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (24 to 35) Physical Damage to Melee Attackers", + armour = { blockChance = 24, evasionBase = 105, energyShieldBase = 31, }, + req = { level = 33, dex = 44, int = 44, }, +} +itemBases["Redwood Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (36 to 50) Physical Damage to Melee Attackers", + armour = { blockChance = 24, evasionBase = 123, energyShieldBase = 36, }, + req = { level = 39, dex = 52, int = 52, }, +} +itemBases["Compound Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (51 to 70) Physical Damage to Melee Attackers", + armour = { blockChance = 25, evasionBase = 106, energyShieldBase = 31, }, + req = { level = 45, dex = 58, int = 58, }, +} +itemBases["Polished Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (71 to 90) Physical Damage to Melee Attackers", + armour = { blockChance = 26, evasionBase = 96, energyShieldBase = 28, }, + req = { level = 49, dex = 64, int = 64, }, +} +itemBases["Sovereign Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (91 to 120) Physical Damage to Melee Attackers", + armour = { blockChance = 24, evasionBase = 169, energyShieldBase = 50, }, + req = { level = 54, dex = 70, int = 70, }, +} +itemBases["Alder Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (121 to 150) Physical Damage to Melee Attackers", + armour = { blockChance = 24, evasionBase = 182, energyShieldBase = 53, }, + req = { level = 58, dex = 74, int = 74, }, +} +itemBases["Ezomyte Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (151 to 180) Physical Damage to Melee Attackers", + armour = { blockChance = 25, evasionBase = 158, energyShieldBase = 46, }, + req = { level = 62, dex = 85, int = 85, }, +} +itemBases["Mirrored Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (181 to 220) Physical Damage to Melee Attackers", + armour = { blockChance = 26, evasionBase = 131, energyShieldBase = 38, }, + req = { level = 66, dex = 85, int = 85, }, +} +itemBases["Supreme Spiked Shield"] = { + type = "Shield", + implicit = "Reflects (221 to 260) Physical Damage to Melee Attackers", + armour = { blockChance = 24, evasionBase = 210, energyShieldBase = 62, }, + req = { level = 70, dex = 85, int = 85, }, +} diff --git a/Items/staff.lua b/Items/staff.lua new file mode 100644 index 00000000..2a35b904 --- /dev/null +++ b/Items/staff.lua @@ -0,0 +1,134 @@ +local itemBases = ... + +itemBases["Gnarled Branch"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 8, physicalMax = 17, critChanceBase = 6.4, attackRateBase = 1.3, }, + req = { }, +} +itemBases["Primitive Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 9, physicalMax = 28, critChanceBase = 6.8, attackRateBase = 1.25, }, + req = { level = 9, str = 20, int = 20, }, +} +itemBases["Long Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 17, physicalMax = 28, critChanceBase = 6.4, attackRateBase = 1.3, }, + req = { level = 13, str = 27, int = 27, }, +} +itemBases["Iron Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 16, physicalMax = 47, critChanceBase = 7, attackRateBase = 1.2, }, + req = { level = 18, str = 35, int = 35, }, +} +itemBases["Coiled Staff"] = { + type = "Staff", + implicit = "18% Chance to Block", + weapon = { physicalMin = 23, physicalMax = 48, critChanceBase = 6.4, attackRateBase = 1.2, }, + req = { level = 23, str = 43, int = 43, }, +} +itemBases["Royal Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 23, physicalMax = 70, critChanceBase = 7.2, attackRateBase = 1.15, }, + req = { level = 28, str = 51, int = 51, }, +} +itemBases["Vile Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 33, physicalMax = 62, critChanceBase = 6.6, attackRateBase = 1.25, }, + req = { level = 33, str = 59, int = 59, }, +} +itemBases["Crescent Staff"] = { + type = "Staff", + implicit = "60% increased Global Critical Strike Chance", + weapon = { physicalMin = 35, physicalMax = 73, critChanceBase = 6.4, attackRateBase = 1.2, }, + req = { level = 36, str = 66, int = 66, }, +} +itemBases["Woodful Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 29, physicalMax = 88, critChanceBase = 6.8, attackRateBase = 1.15, }, + req = { level = 37, str = 65, int = 65, }, +} +itemBases["Quarterstaff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 41, physicalMax = 68, critChanceBase = 6.4, attackRateBase = 1.3, }, + req = { level = 41, str = 72, int = 72, }, +} +itemBases["Military Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 34, physicalMax = 101, critChanceBase = 7, attackRateBase = 1.2, }, + req = { level = 45, str = 78, int = 78, }, +} +itemBases["Serpentine Staff"] = { + type = "Staff", + implicit = "18% Chance to Block", + weapon = { physicalMin = 46, physicalMax = 95, critChanceBase = 6.4, attackRateBase = 1.2, }, + req = { level = 49, str = 85, int = 85, }, +} +itemBases["Highborn Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 42, physicalMax = 125, critChanceBase = 7.2, attackRateBase = 1.15, }, + req = { level = 52, str = 89, int = 89, }, +} +itemBases["Foul Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 55, physicalMax = 103, critChanceBase = 6.6, attackRateBase = 1.25, }, + req = { level = 55, str = 94, int = 94, }, +} +itemBases["Moon Staff"] = { + type = "Staff", + implicit = "60% increased Global Critical Strike Chance", + weapon = { physicalMin = 57, physicalMax = 118, critChanceBase = 6.4, attackRateBase = 1.2, }, + req = { level = 57, str = 101, int = 101, }, +} +itemBases["Primordial Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 47, physicalMax = 141, critChanceBase = 6.8, attackRateBase = 1.15, }, + req = { level = 58, str = 99, int = 99, }, +} +itemBases["Lathi"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 62, physicalMax = 103, critChanceBase = 6.4, attackRateBase = 1.3, }, + req = { level = 60, str = 113, int = 113, }, +} +itemBases["Ezomyte Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 46, physicalMax = 138, critChanceBase = 7, attackRateBase = 1.2, }, + req = { level = 62, str = 113, int = 113, }, +} +itemBases["Maelström Staff"] = { + type = "Staff", + implicit = "18% Chance to Block", + weapon = { physicalMin = 57, physicalMax = 119, critChanceBase = 6.4, attackRateBase = 1.2, }, + req = { level = 64, str = 113, int = 113, }, +} +itemBases["Imperial Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 49, physicalMax = 147, critChanceBase = 7.2, attackRateBase = 1.15, }, + req = { level = 66, str = 113, int = 113, }, +} +itemBases["Judgement Staff"] = { + type = "Staff", + implicit = "12% Chance to Block", + weapon = { physicalMin = 61, physicalMax = 113, critChanceBase = 6.6, attackRateBase = 1.25, }, + req = { level = 68, str = 113, int = 113, }, +} +itemBases["Eclipse Staff"] = { + type = "Staff", + implicit = "80% increased Global Critical Strike Chance", + weapon = { physicalMin = 60, physicalMax = 125, critChanceBase = 6.4, attackRateBase = 1.2, }, + req = { level = 70, str = 117, int = 117, }, +} diff --git a/Items/sword.lua b/Items/sword.lua new file mode 100644 index 00000000..c9da756a --- /dev/null +++ b/Items/sword.lua @@ -0,0 +1,439 @@ +local itemBases = ... + +itemBases["Rusted Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 4, physicalMax = 8, critChanceBase = 5, attackRateBase = 1.45, }, + req = { level = 1, str = 8, dex = 8, }, +} +itemBases["Copper Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 6, physicalMax = 12, critChanceBase = 5, attackRateBase = 1.4, }, + req = { level = 5, str = 14, dex = 14, }, +} +itemBases["Sabre"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 4, physicalMax = 18, critChanceBase = 5, attackRateBase = 1.55, }, + req = { level = 10, str = 18, dex = 26, }, +} +itemBases["Broad Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 14, physicalMax = 21, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 15, str = 30, dex = 30, }, +} +itemBases["War Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 16, physicalMax = 30, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 20, str = 41, dex = 35, }, +} +itemBases["Ancient Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 17, physicalMax = 31, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 24, str = 44, dex = 44, }, +} +itemBases["Elegant Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 17, physicalMax = 27, critChanceBase = 5, attackRateBase = 1.5, }, + req = { level = 28, str = 46, dex = 55, }, +} +itemBases["Dusk Blade"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 15, physicalMax = 43, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 32, str = 57, dex = 57, }, +} +itemBases["Hook Sword"] = { + type = "One Handed Sword", + implicit = "2% chance to Dodge Attacks", + weapon = { physicalMin = 23, physicalMax = 49, critChanceBase = 5, attackRateBase = 1.15, }, + req = { level = 34, str = 64, dex = 64, }, +} +itemBases["Variscite Blade"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 20, physicalMax = 43, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 35, str = 62, dex = 62, }, +} +itemBases["Cutlass"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 11, physicalMax = 44, critChanceBase = 5, attackRateBase = 1.55, }, + req = { level = 38, str = 55, dex = 79, }, +} +itemBases["Baselard"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 29, physicalMax = 42, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 41, str = 72, dex = 72, }, +} +itemBases["Battle Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 30, physicalMax = 55, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 44, str = 83, dex = 70, }, +} +itemBases["Elder Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 28, physicalMax = 52, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 47, str = 81, dex = 81, }, +} +itemBases["Graceful Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 27, physicalMax = 44, critChanceBase = 5, attackRateBase = 1.5, }, + req = { level = 50, str = 78, dex = 94, }, +} +itemBases["Twilight Blade"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 23, physicalMax = 66, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 53, str = 91, dex = 91, }, +} +itemBases["Grappler"] = { + type = "One Handed Sword", + implicit = "2% chance to Dodge Attacks", + weapon = { physicalMin = 35, physicalMax = 75, critChanceBase = 5, attackRateBase = 1.15, }, + req = { level = 55, str = 99, dex = 99, }, +} +itemBases["Gemstone Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 30, physicalMax = 64, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 56, str = 96, dex = 96, }, +} +itemBases["Corsair Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 16, physicalMax = 63, critChanceBase = 5, attackRateBase = 1.55, }, + req = { level = 58, str = 81, dex = 117, }, +} +itemBases["Gladius"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 41, physicalMax = 59, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 60, str = 113, dex = 113, }, +} +itemBases["Legion Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 39, physicalMax = 73, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 62, str = 122, dex = 104, }, +} +itemBases["Vaal Blade"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 35, physicalMax = 65, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 64, str = 113, dex = 113, }, +} +itemBases["Eternal Sword"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 32, physicalMax = 52, critChanceBase = 5, attackRateBase = 1.5, }, + req = { level = 66, str = 104, dex = 122, }, +} +itemBases["Midnight Blade"] = { + type = "One Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 26, physicalMax = 74, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 68, str = 113, dex = 113, }, +} +itemBases["Tiger Hook"] = { + type = "One Handed Sword", + implicit = "3% chance to Dodge Attacks", + weapon = { physicalMin = 43, physicalMax = 92, critChanceBase = 5, attackRateBase = 1.15, }, + req = { level = 70, str = 119, dex = 119, }, +} + + +itemBases["Rusted Spike"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 4, physicalMax = 10, critChanceBase = 5.5, attackRateBase = 1.4, }, + req = { dex = 20, }, +} +itemBases["Whalebone Rapier"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 4, physicalMax = 15, critChanceBase = 5.5, attackRateBase = 1.55, }, + req = { level = 7, dex = 32, }, +} +itemBases["Battered Foil"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 10, physicalMax = 18, critChanceBase = 6, attackRateBase = 1.4, }, + req = { level = 12, dex = 47, }, +} +itemBases["Basket Rapier"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 9, physicalMax = 22, critChanceBase = 5.5, attackRateBase = 1.5, }, + req = { level = 17, dex = 62, }, +} +itemBases["Jagged Foil"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 11, physicalMax = 25, critChanceBase = 5.5, attackRateBase = 1.6, }, + req = { level = 22, dex = 77, }, +} +itemBases["Antique Rapier"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 10, physicalMax = 40, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 26, dex = 89, }, +} +itemBases["Elegant Foil"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 15, physicalMax = 28, critChanceBase = 5.5, attackRateBase = 1.6, }, + req = { level = 30, dex = 101, }, +} +itemBases["Thorn Rapier"] = { + type = "One Handed Sword", + implicit = "+50% to Global Critical Strike Multiplier", + weapon = { physicalMin = 16, physicalMax = 37, critChanceBase = 5.7, attackRateBase = 1.4, }, + req = { level = 34, dex = 113, }, +} +itemBases["Smallsword"] = { + type = "One Handed Sword", + implicit = "8% chance to cause Bleeding on Hit", + weapon = { physicalMin = 17, physicalMax = 36, critChanceBase = 6, attackRateBase = 1.55, }, + req = { level = 36, dex = 124, }, +} +itemBases["Wyrmbone Rapier"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 11, physicalMax = 44, critChanceBase = 5.5, attackRateBase = 1.5, }, + req = { level = 37, dex = 122, }, +} +itemBases["Burnished Foil"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 22, physicalMax = 41, critChanceBase = 6, attackRateBase = 1.4, }, + req = { level = 40, dex = 131, }, +} +itemBases["Estoc"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 19, physicalMax = 44, critChanceBase = 5.5, attackRateBase = 1.5, }, + req = { level = 43, dex = 140, }, +} +itemBases["Serrated Foil"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 19, physicalMax = 43, critChanceBase = 5.5, attackRateBase = 1.6, }, + req = { level = 46, dex = 149, }, +} +itemBases["Primeval Rapier"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 17, physicalMax = 67, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 49, dex = 158, }, +} +itemBases["Fancy Foil"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 24, physicalMax = 45, critChanceBase = 5.5, attackRateBase = 1.6, }, + req = { level = 52, dex = 167, }, +} +itemBases["Apex Rapier"] = { + type = "One Handed Sword", + implicit = "+50% to Global Critical Strike Multiplier", + weapon = { physicalMin = 24, physicalMax = 55, critChanceBase = 5.7, attackRateBase = 1.4, }, + req = { level = 55, dex = 176, }, +} +itemBases["Courtesan Sword"] = { + type = "One Handed Sword", + implicit = "8% chance to cause Bleeding on Hit", + weapon = { physicalMin = 26, physicalMax = 53, critChanceBase = 6, attackRateBase = 1.55, }, + req = { level = 57, dex = 190, }, +} +itemBases["Dragonbone Rapier"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 16, physicalMax = 65, critChanceBase = 5.5, attackRateBase = 1.5, }, + req = { level = 58, dex = 185, }, +} +itemBases["Tempered Foil"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 31, physicalMax = 58, critChanceBase = 6, attackRateBase = 1.4, }, + req = { level = 60, dex = 212, }, +} +itemBases["Pecoraro"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 25, physicalMax = 59, critChanceBase = 5.5, attackRateBase = 1.5, }, + req = { level = 62, dex = 212, }, +} +itemBases["Spiraled Foil"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 24, physicalMax = 55, critChanceBase = 5.5, attackRateBase = 1.6, }, + req = { level = 64, dex = 212, }, +} +itemBases["Vaal Rapier"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 20, physicalMax = 80, critChanceBase = 6.5, attackRateBase = 1.3, }, + req = { level = 66, dex = 212, }, +} +itemBases["Jewelled Foil"] = { + type = "One Handed Sword", + implicit = "+30% to Global Critical Strike Multiplier", + weapon = { physicalMin = 27, physicalMax = 51, critChanceBase = 5.5, attackRateBase = 1.6, }, + req = { level = 68, dex = 212, }, +} +itemBases["Harpy Rapier"] = { + type = "One Handed Sword", + implicit = "+50% to Global Critical Strike Multiplier", + weapon = { physicalMin = 26, physicalMax = 60, critChanceBase = 5.7, attackRateBase = 1.4, }, + req = { level = 70, dex = 212, }, +} +itemBases["Dragoon Sword"] = { + type = "One Handed Sword", + implicit = "12% chance to cause Bleeding on Hit", + weapon = { physicalMin = 28, physicalMax = 58, critChanceBase = 6, attackRateBase = 1.5, }, + req = { level = 72, dex = 220, }, +} + + +itemBases["Corroded Blade"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 7, physicalMax = 14, critChanceBase = 5, attackRateBase = 1.35, }, + req = { }, +} +itemBases["Longsword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 14, physicalMax = 33, critChanceBase = 5, attackRateBase = 1.1, }, + req = { level = 8, str = 20, dex = 17, }, +} +itemBases["Bastard Sword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 15, physicalMax = 25, critChanceBase = 5, attackRateBase = 1.35, }, + req = { level = 12, str = 21, dex = 30, }, +} +itemBases["Two-Handed Sword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 23, physicalMax = 43, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 17, str = 33, dex = 33, }, +} +itemBases["Etched Greatsword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 29, physicalMax = 61, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 22, str = 45, dex = 38, }, +} +itemBases["Ornate Sword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 32, physicalMax = 53, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 27, str = 45, dex = 54, }, +} +itemBases["Spectral Sword"] = { + type = "Two Handed Sword", + implicit = "30% increased Accuracy Rating", + weapon = { physicalMin = 35, physicalMax = 73, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 32, str = 57, dex = 57, }, +} +itemBases["Curved Blade"] = { + type = "Two Handed Sword", + implicit = "+40% to Global Critical Strike Multiplier", + weapon = { physicalMin = 39, physicalMax = 65, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 35, str = 62, dex = 73, }, +} +itemBases["Butcher Sword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 40, physicalMax = 93, critChanceBase = 5, attackRateBase = 1.1, }, + req = { level = 36, str = 69, dex = 58, }, +} +itemBases["Footman Sword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 42, physicalMax = 70, critChanceBase = 5, attackRateBase = 1.35, }, + req = { level = 40, str = 57, dex = 83, }, +} +itemBases["Highland Blade"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 50, physicalMax = 92, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 44, str = 77, dex = 77, }, +} +itemBases["Engraved Greatsword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 55, physicalMax = 115, critChanceBase = 5, attackRateBase = 1.1, }, + req = { level = 48, str = 91, dex = 76, }, +} +itemBases["Tiger Sword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 55, physicalMax = 91, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 51, str = 80, dex = 96, }, +} +itemBases["Wraith Sword"] = { + type = "Two Handed Sword", + implicit = "30% increased Accuracy Rating", + weapon = { physicalMin = 55, physicalMax = 114, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 54, str = 93, dex = 93, }, +} +itemBases["Lithe Blade"] = { + type = "Two Handed Sword", + implicit = "+40% to Global Critical Strike Multiplier", + weapon = { physicalMin = 63, physicalMax = 105, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 56, str = 96, dex = 113, }, +} +itemBases["Headman's Sword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 59, physicalMax = 139, critChanceBase = 5, attackRateBase = 1.1, }, + req = { level = 57, str = 106, dex = 89, }, +} +itemBases["Reaver Sword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 59, physicalMax = 99, critChanceBase = 5, attackRateBase = 1.35, }, + req = { level = 59, str = 82, dex = 119, }, +} +itemBases["Ezomyte Blade"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 65, physicalMax = 121, critChanceBase = 5, attackRateBase = 1.2, }, + req = { level = 61, str = 113, dex = 113, }, +} +itemBases["Vaal Greatsword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 67, physicalMax = 140, critChanceBase = 5, attackRateBase = 1.1, }, + req = { level = 63, str = 122, dex = 104, }, +} +itemBases["Lion Sword"] = { + type = "Two Handed Sword", + implicit = "18% increased Accuracy Rating", + weapon = { physicalMin = 63, physicalMax = 105, critChanceBase = 5, attackRateBase = 1.3, }, + req = { level = 65, str = 104, dex = 122, }, +} +itemBases["Infernal Sword"] = { + type = "Two Handed Sword", + implicit = "30% increased Accuracy Rating", + weapon = { physicalMin = 57, physicalMax = 118, critChanceBase = 5, attackRateBase = 1.25, }, + req = { level = 67, str = 113, dex = 113, }, +} +itemBases["Exquisite Blade"] = { + type = "Two Handed Sword", + implicit = "+60% to Global Critical Strike Multiplier", + weapon = { physicalMin = 68, physicalMax = 114, critChanceBase = 6, attackRateBase = 1.25, }, + req = { level = 70, str = 119, dex = 131, }, +} + diff --git a/Items/wand.lua b/Items/wand.lua new file mode 100644 index 00000000..4894ba11 --- /dev/null +++ b/Items/wand.lua @@ -0,0 +1,116 @@ +local itemBases = ... + +itemBases["Driftwood Wand"] = { + type = "Wand", + implicit = "(8 to 12)% increased Spell Damage", + weapon = { physicalMin = 3, physicalMax = 6, critChanceBase = 8, attackRateBase = 1.4, }, + req = { level = 1, int = 14, }, +} +itemBases["Goat's Horn"] = { + type = "Wand", + implicit = "(9 to 12)% increased Spell Damage", + weapon = { physicalMin = 5, physicalMax = 10, critChanceBase = 8, attackRateBase = 1.2, }, + req = { level = 6, int = 29, }, +} +itemBases["Carved Wand"] = { + type = "Wand", + implicit = "(9 to 13)% increased Spell Damage", + weapon = { physicalMin = 6, physicalMax = 11, critChanceBase = 8, attackRateBase = 1.5, }, + req = { level = 12, int = 47, }, +} +itemBases["Quartz Wand"] = { + type = "Wand", + implicit = "(11 to 15)% increased Spell Damage", + weapon = { physicalMin = 9, physicalMax = 17, critChanceBase = 8, attackRateBase = 1.3, }, + req = { level = 18, int = 65, }, +} +itemBases["Spiraled Wand"] = { + type = "Wand", + implicit = "(10 to 14)% increased Spell Damage", + weapon = { physicalMin = 8, physicalMax = 24, critChanceBase = 8, attackRateBase = 1.3, }, + req = { level = 24, int = 83, }, +} +itemBases["Sage Wand"] = { + type = "Wand", + implicit = "(11 to 14)% increased Spell Damage", + weapon = { physicalMin = 15, physicalMax = 28, critChanceBase = 9, attackRateBase = 1.2, }, + req = { level = 30, int = 119, }, +} +itemBases["Pagan Wand"] = { + type = "Wand", + implicit = "4% increased Cast Speed", + weapon = { physicalMin = 14, physicalMax = 26, critChanceBase = 8, attackRateBase = 1.35, }, + req = { level = 34, int = 118, }, +} +itemBases["Faun's Horn"] = { + type = "Wand", + implicit = "(12 to 15)% increased Spell Damage", + weapon = { physicalMin = 17, physicalMax = 32, critChanceBase = 8, attackRateBase = 1.2, }, + req = { level = 35, int = 116, }, +} +itemBases["Engraved Wand"] = { + type = "Wand", + implicit = "(12 to 16)% increased Spell Damage", + weapon = { physicalMin = 14, physicalMax = 27, critChanceBase = 8, attackRateBase = 1.5, }, + req = { level = 40, int = 131, }, +} +itemBases["Crystal Wand"] = { + type = "Wand", + implicit = "(14 to 18)% increased Spell Damage", + weapon = { physicalMin = 19, physicalMax = 35, critChanceBase = 8, attackRateBase = 1.3, }, + req = { level = 45, int = 146, }, +} +itemBases["Serpent Wand"] = { + type = "Wand", + implicit = "(13 to 17)% increased Spell Damage", + weapon = { physicalMin = 15, physicalMax = 44, critChanceBase = 8, attackRateBase = 1.3, }, + req = { level = 49, int = 158, }, +} +itemBases["Omen Wand"] = { + type = "Wand", + implicit = "(14 to 17)% increased Spell Damage", + weapon = { physicalMin = 25, physicalMax = 46, critChanceBase = 9, attackRateBase = 1.2, }, + req = { level = 53, int = 200, }, +} +itemBases["Heathen Wand"] = { + type = "Wand", + implicit = "4% increased Cast Speed", + weapon = { physicalMin = 21, physicalMax = 40, critChanceBase = 8, attackRateBase = 1.35, }, + req = { level = 55, int = 184, }, +} +itemBases["Demon's Horn"] = { + type = "Wand", + implicit = "(15 to 18)% increased Spell Damage", + weapon = { physicalMin = 26, physicalMax = 48, critChanceBase = 8, attackRateBase = 1.2, }, + req = { level = 56, int = 179, }, +} +itemBases["Imbued Wand"] = { + type = "Wand", + implicit = "(15 to 19)% increased Spell Damage", + weapon = { physicalMin = 20, physicalMax = 38, critChanceBase = 8, attackRateBase = 1.5, }, + req = { level = 59, int = 188, }, +} +itemBases["Opal Wand"] = { + type = "Wand", + implicit = "(17 to 20)% increased Spell Damage", + weapon = { physicalMin = 24, physicalMax = 45, critChanceBase = 8, attackRateBase = 1.3, }, + req = { level = 62, int = 212, }, +} +itemBases["Tornado Wand"] = { + type = "Wand", + implicit = "(16 to 19)% increased Spell Damage", + weapon = { physicalMin = 17, physicalMax = 52, critChanceBase = 8, attackRateBase = 1.3, }, + req = { level = 65, int = 212, }, +} +itemBases["Prophecy Wand"] = { + type = "Wand", + implicit = "(16 to 20)% increased Spell Damage", + weapon = { physicalMin = 27, physicalMax = 51, critChanceBase = 9, attackRateBase = 1.2, }, + req = { level = 68, int = 245, }, +} +itemBases["Profane Wand"] = { + type = "Wand", + implicit = "6% increased Cast Speed", + weapon = { physicalMin = 23, physicalMax = 43, critChanceBase = 8, attackRateBase = 1.35, }, + req = { level = 70, int = 237, }, +} diff --git a/Launch.lua b/Launch.lua new file mode 100644 index 00000000..64abf240 --- /dev/null +++ b/Launch.lua @@ -0,0 +1,129 @@ +#@ SimpleGraphic + +SetWindowTitle("PathOfBuilding") + +LoadModule("Common") + +local launch = { } + +function launch:LoadMain() + ConPrintf("Loading main script...") + if self.main and self.main.Shutdown then + PCall(self.main.Shutdown, self.main) + end + self.main = nil + collectgarbage("collect") + local errMsg + errMsg, self.main = PLoadModule("main", launch) + if errMsg then + self:ShowErrMsg("Error loading main script: %s", errMsg) + elseif not self.main then + self:ShowErrMsg("Error loading main script: no object returned") + elseif self.main.Init then + errMsg = PCall(self.main.Init, self.main) + if errMsg then + self:ShowErrMsg("In 'Init': %s", errMsg) + end + end +end + +function launch:ShowPrompt(r, g, b, str, func) + if self.promptMsg then + return + end + self.promptMsg = str + self.promptCol = {r, g, b} + self.promptFunc = func or function(key) + if key == "RETURN" or key == "ESCAPE" then + return true + end + end +end + +function launch:ShowErrMsg(fmt, ...) + self:ShowPrompt(1, 0, 0, "^1Error:\n\n^0" .. string.format(fmt, ...) .. "\n\nEnter/Escape to Dismiss, F5 to reload scripts", function(key) + if key == "RETURN" or key == "ESCAPE" then + return true + end + end) +end + +launch:LoadMain() + +SetCallback("OnFrame", function() + if launch.main then + if launch.main.OnFrame then + local errMsg = PCall(launch.main.OnFrame, launch.main) + if errMsg then + launch:ShowErrMsg("In 'OnFrame': %s", errMsg) + end + end + end + if launch.promptMsg then + local r, g, b = unpack(launch.promptCol) + common.drawPopup(r, g, b, "^0%s", launch.promptMsg) + end + if launch.doReload then + local screenW, screenH = GetScreenSize() + SetDrawColor(0, 0, 0, 0.75) + DrawImage(nil, 0, 0, screenW, screenH) + SetDrawColor(1, 1, 1) + DrawString(0, screenH/2, "CENTER", 24, "FIXED", "Reloading...") + Restart() + end +end) + +SetCallback("OnKeyDown", function(key, doubleClick) + if key == "F5" then + launch.doReload = true + elseif launch.promptMsg then + local errMsg, ret = PCall(launch.promptFunc, key) + if errMsg then + launch:ShowErrMsg("In prompt func: %s", errMsg) + elseif ret then + launch.promptMsg = nil + end + else + if launch.main and launch.main.OnKeyDown then + local errMsg = PCall(launch.main.OnKeyDown, launch.main, key, doubleClick) + if errMsg then + launch:ShowErrMsg("In 'OnKeyDown': %s", errMsg) + end + end + end +end) + +SetCallback("OnKeyUp", function(key) + if not launch.promptMsg then + if launch.main and launch.main.OnKeyUp then + local errMsg = PCall(launch.main.OnKeyUp, launch.main, key) + if errMsg then + launch:ShowErrMsg("In 'OnKeyUp': %s", errMsg) + end + end + end +end) + +SetCallback("OnChar", function(key) + if launch.promptMsg then + local errMsg, ret = PCall(launch.promptFunc, key) + if errMsg then + launch:ShowErrMsg("In prompt func: %s", errMsg) + elseif ret then + launch.promptMsg = nil + end + else + if launch.main and launch.main.OnChar then + local errMsg = PCall(launch.main.OnChar, launch.main, key) + if errMsg then + launch:ShowErrMsg("In 'OnChar': %s", errMsg) + end + end + end +end) + +SetCallback("OnExit", function() + if launch.main and launch.main.Shutdown then + PCall(launch.main.Shutdown, launch.main) + end +end) \ No newline at end of file diff --git a/List.lua b/List.lua new file mode 100644 index 00000000..578dc63d --- /dev/null +++ b/List.lua @@ -0,0 +1,311 @@ +local launch, cfg, main = ... + +local vfs = require("vfs") + +local listMode = { } + +listMode.controls = { + common.newButton(2, 2, 60, 20, "New", function() + listMode:New() + end), + common.newButton(66, 2, 60, 20, "Copy", function() + listMode:CopySel() + end, function() + return listMode.sel ~= nil + end), + common.newButton(130, 2, 60, 20, "Rename", function() + listMode:RenameSel() + end, function() + return listMode.sel ~= nil + end), + common.newButton(194, 2, 60, 20, "Delete", function() + listMode:DeleteSel() + end, function() + return listMode.sel ~= nil + end), +} + +function listMode:BuildList() + self.list = { } + vfs.scan(true) + for _, file in ipairs(vfs.root.files) do + if file.name:lower():match("%.xml$") and file.name:lower() ~= "settings.xml" then + local build = { } + build.fileName = file.name + local dbXML, errMsg = common.xml.LoadXMLFile(file.name) + if dbXML and dbXML[1].elem == "PathOfBuilding" then + for _, node in ipairs(dbXML[1]) do + if type(node) == "table" and node.elem == "Build" then + build.className = node.attrib.className + build.ascendClassName = node.attrib.ascendClassName + build.level = tonumber(node.attrib.level) or 1 + end + end + end + table.insert(self.list, build) + end + end + self:SortList() +end + +function listMode:SortList() + local oldSelFileName = self.sel and self.list[self.sel].fileName + table.sort(self.list, function(a, b) return a.fileName:upper() < b.fileName:upper() end) + if oldSelFileName then + self:SelFileByName(oldSelFileName) + end +end + +function listMode:EditInit(finFunc) + self.edit = self.sel + self.editFinFunc = finFunc + self.editField = common.newEditField(self.list[self.sel].fileName:gsub(".xml$",""), nil, "[%w _+.()]") + self.editField.x = 2 + self.editField.y = 6 + self.sel * 20 + self.editField.width = cfg.screenW + self.editField.height = 16 +end + +function listMode:EditFinish() + local msg = self.editFinFunc(self.editField.buf) + if msg then + launch:ShowPrompt(1, 0.5, 0, msg.."\n\nEnter/Escape to dismiss") + return + end + self.edit = nil + self.editField = nil +end + +function listMode:EditCancel() + self.sel = nil + self.edit = nil + self.editField = nil + self:BuildList() +end + +function listMode:New() + table.insert(self.list, 1, { fileName = "", level = 1 }) + self.sel = 1 + self:EditInit(function(buf) + if #buf < 1 then + return "No name entered" + end + local fileName = buf .. ".xml" + local outFile, msg = io.open(fileName, "r") + if outFile then + outFile:close() + return "'"..fileName.."' already exists" + end + outFile, msg = io.open(fileName, "w") + if not outFile then + return "Couldn't create '"..fileName.."': "..msg + end + outFile:write('\n\n') + outFile:close() + self.list[self.sel].fileName = fileName + self:SortList() + end) +end + +function listMode:CopySel() + local srcName = self.list[self.sel].fileName + table.insert(self.list, self.sel + 1, copyTable(self.list[self.sel])) + self.sel = self.sel + 1 + self.list[self.sel].fileName = srcName:gsub(".xml$","") .. " (copy)" + self:EditInit(function(buf) + if #buf < 1 then + return "No name entered" + end + local inFile, msg = io.open(srcName, "r") + if not inFile then + return "Couldn't copy '"..srcName.."': "..msg + end + local dstName = buf .. ".xml" + local outFile, msg = io.open(dstName, "r") + if outFile then + outFile:close() + return "'"..dstName.."' already exists" + end + outFile, msg = io.open(dstName, "w") + if not outFile then + return "Couldn't create '"..dstName.."': "..msg + end + outFile:write(inFile:read("*a")) + inFile:close() + outFile:close() + self.list[self.sel].fileName = dstName + self:SortList() + end) +end + +function listMode:RenameSel() + local oldName = self.list[self.sel].fileName + self:EditInit(function(buf) + if #buf < 1 then + return "No name entered" + end + local newName = buf .. ".xml" + if newName == oldName then + return + end + if newName:lower() ~= oldName:lower() then + local newFile = io.open(newName, "r") + if newFile then + newFile:close() + return "'"..newName.."' already exists" + end + end + local res, msg = os.rename(oldName, newName) + if not res then + return "Couldn't rename '"..oldName.."' to '"..newName.."': "..msg + end + self.list[self.sel].fileName = newName + self:SortList() + end) +end + +function listMode:DeleteSel() + launch:ShowPrompt(1, 0, 0, "Are you sure you want to delete\n'"..self.list[self.sel].fileName.."' ? (y/n)", function(key) + if key == "y" then + os.remove(self.list[self.sel].fileName) + self:BuildList() + self.sel = nil + end + return true + end) +end + +function listMode:SelFileByName(selFileName) + self.sel = nil + for index, build in ipairs(self.list) do + if build.fileName == selFileName then + self.sel = index + break + end + end +end + +function listMode:Init(selFileName) + self:BuildList() + self:SelFileByName(selFileName) +end + +function listMode:Shutdown() + if self.edit then + self:EditCancel() + end +end + +function listMode:OnFrame(inputEvents) + for id, event in ipairs(inputEvents) do + if event.type == "KeyDown" then + self:OnKeyDown(event.key, event.doubleClick) + elseif event.type == "KeyUp" then + self:OnKeyUp(event.key) + elseif event.type == "Char" then + self:OnChar(event.key) + end + end + common.controlsDraw(self) + for index, build in ipairs(self.list) do + local y = 4 + index * 20 + if self.sel == index then + SetDrawColor(1, 1, 1) + else + SetDrawColor(0.5, 0.5, 0.5) + end + DrawImage(nil, 0, y, cfg.screenW, 20) + if self.sel == index then + SetDrawColor(0.33, 0.33, 0.33) + else + SetDrawColor(0, 0, 0) + end + DrawImage(nil, 0, y + 1, cfg.screenW, 18) + if self.edit == index then + self.editField:Draw(2, y + 2, 16) + else + if self.sel == index then + SetDrawColor(1, 1, 1) + else + SetDrawColor(0.8, 0.8, 0.8) + end + DrawString(4, y + 2, "LEFT", 16, "VAR", build.fileName:gsub(".xml","")) + DrawString(304, y + 2, "LEFT", 16, "VAR", string.format("Level %d %s", build.level, build.ascendClassName or build.className or "?")) + end + end +end + +function listMode:OnKeyDown(key, doubleClick) + if self.edit then + if key == "RETURN" then + self:EditFinish() + elseif key == "ESCAPE" then + self:EditCancel() + else + self.editField:OnKeyDown(key) + end + elseif key == "LEFTBUTTON" then + self.selControl = nil + local cx, cy = GetCursorPos() + for _, control in pairs(self.controls) do + if control.IsMouseOver and control:IsMouseOver() then + control:OnKeyDown(key) + self.selControl = control + return + end + end + self.sel = nil + for index, fileName in ipairs(self.list) do + local y = 4 + index * 20 + if cy >= y and cy < y + 20 then + if doubleClick then + main:SetMode("BUILD", self.list[index].fileName) + else + self.sel = index + end + return + end + end + elseif key == "RETURN" then + if self.sel then + main:SetMode("BUILD", self.list[self.sel].fileName) + end + elseif key == "UP" then + if not self.sel then + self.sel = #self.list + else + self.sel = (self.sel - 2) % #self.list + 1 + end + elseif key == "DOWN" then + if not self.sel then + self.sel = 1 + else + self.sel = self.sel % #self.list + 1 + end + elseif key == "F2" then + if self.sel then + self:RenameSel() + end + elseif key == "DELETE" then + if self.sel then + self:DeleteSel() + end + end +end + +function listMode:OnKeyUp(key) + if self.edit then + self.editField:OnKeyUp(key) + elseif self.selControl then + self.selControl:OnKeyUp(key) + self.selControl = nil + end +end + +function listMode:OnChar(key) + if self.edit then + self.editField:OnChar(key) + end +end + +return listMode \ No newline at end of file diff --git a/Main.lua b/Main.lua new file mode 100644 index 00000000..f6175abd --- /dev/null +++ b/Main.lua @@ -0,0 +1,203 @@ +local launch = ... + +local ipairs = ipairs +local m_floor = math.floor +local m_max = math.max +local t_insert = table.insert + +local cfg = { } + +local main = { } + +main.tooltipLines = { } +function main:AddTooltipLine(size, text) + for line in string.gmatch(text .. "\n", "([^\n]*)\n") do + t_insert(self.tooltipLines, { size = size, text = line }) + end +end +function main:AddTooltipSeperator(size) + t_insert(self.tooltipLines, { size = size }) +end +function main:DrawTooltip(x, y, w, h, viewPort, col, center) + local ttW, ttH = 0, 0 + for _, data in ipairs(self.tooltipLines) do + ttH = ttH + data.size + 2 + if data.text then + ttW = m_max(ttW, DrawStringWidth(data.size, "VAR", data.text)) + end + end + ttW = ttW + 12 + ttH = ttH + 10 + local ttX = x + local ttY = y + if w and h then + ttX = ttX + w + 5 + if ttX + ttW > viewPort.x + viewPort.width then + ttX = m_max(viewPort.x, x - 5 - ttW) + end + if ttY + ttH > viewPort.y + viewPort.height then + ttY = m_max(viewPort.y, y + h - ttH) + end + elseif center then + ttX = m_floor(x - ttW/2) + end + col = col or { 0.5, 0.3, 0 } + if type(col) == "string" then + SetDrawColor(col) + else + SetDrawColor(unpack(col)) + end + DrawImage(nil, ttX, ttY, ttW, 3) + DrawImage(nil, ttX, ttY, 3, ttH) + DrawImage(nil, ttX, ttY + ttH - 3, ttW, 3) + DrawImage(nil, ttX + ttW - 3, ttY, 3, ttH) + SetDrawColor(0, 0, 0, 0.75) + DrawImage(nil, ttX + 3, ttY + 3, ttW - 6, ttH - 6) + SetDrawColor(1, 1, 1) + local y = ttY + 6 + for i, data in ipairs(self.tooltipLines) do + if data.text then + if center then + DrawString(ttX + ttW/2, y, "CENTER_X", data.size, "VAR", data.text) + else + DrawString(ttX + 6, y, "LEFT", data.size, "VAR", data.text) + end + else + if type(col) == "string" then + SetDrawColor(col) + else + SetDrawColor(unpack(col)) + end + DrawImage(nil, ttX + 3, y - 1 + data.size / 2, ttW - 6, 2) + end + y = y + data.size + 2 + self.tooltipLines[i] = nil + end +end + +LoadModule("Data") +LoadModule("ModTools") + +main.TreeClass = LoadModule("Tree", launch, cfg, main) +main.SpecClass = LoadModule("Spec", launch, cfg, main) +main.TreeViewClass = LoadModule("TreeView", launch, cfg, main) + +main.modes = { } +main.modes["LIST"] = LoadModule("List", launch, cfg, main) +main.modes["BUILD"] = LoadModule("Build", launch, cfg, main) + +function main:SetMode(newMode, ...) + self.newMode = newMode + self.newModeArgs = {...} +end + +function main:CallMode(func, ...) + local modeTbl = self.modes[self.mode] + if modeTbl[func] then + modeTbl[func](modeTbl, ...) + end +end + +function main:LoadSettings() + local setXML, errMsg = common.xml.LoadXMLFile("Settings.xml") + if not setXML then + return true + elseif setXML[1].elem ~= "PathOfBuilding" then + launch:ShowErrMsg("^1Error parsing 'Settings.xml': 'PathOfBuilding' root element missing") + return true + end + for _, node in ipairs(setXML[1]) do + if type(node) == "table" then + if node.elem == "Mode" then + if not node.attrib.mode or not self.modes[node.attrib.mode] then + launch:ShowErrMsg("^1Error parsing 'Settings.xml': Invalid mode attribute in 'Mode' element") + return true + end + local args = { } + for _, child in ipairs(node) do + if type(child) == "table" then + if child.elem == "Arg" then + if child.attrib.number then + t_insert(args, tonumber(child.attrib.number)) + elseif child.attrib.string then + t_insert(args, child.attrib.string) + elseif child.attrib.boolean then + t_insert(args, child.attrib.boolean == "true") + end + end + end + end + self:SetMode(node.attrib.mode, unpack(args)) + end + end + end +end +function main:SaveSettings() + local setXML = { elem = "PathOfBuilding" } + local mode = { elem = "Mode", attrib = { mode = self.mode } } + for _, val in ipairs(self.modeArgs) do + local child = { elem = "Arg", attrib = {} } + if type(val) == "number" then + child.attrib.number = tostring(val) + elseif type(val) == "boolean" then + child.attrib.boolean = tostring(val) + else + child.attrib.string = tostring(val) + end + t_insert(mode, child) + end + t_insert(setXML, mode) + local res, errMsg = common.xml.SaveXMLFile(setXML, "Settings.xml") + if not res then + launch:ShowErrMsg("Error saving 'Settings.xml': %s", errMsg) + return true + end +end + +function main:OnFrame() + cfg.screenW, cfg.screenH = GetScreenSize() + + if self.newMode then + if self.mode then + self:CallMode("Shutdown") + end + self.mode = self.newMode + self.modeArgs = self.newModeArgs + self.newMode = nil + self:CallMode("Init", unpack(self.modeArgs)) + end + + self:CallMode("OnFrame", self.inputEvents) + + wipeTable(self.inputEvents) +end + +function main:OnKeyDown(key, doubleClick) + t_insert(self.inputEvents, { type = "KeyDown", key = key, doubleClick = doubleClick }) +end + +function main:OnKeyUp(key) + t_insert(self.inputEvents, { type = "KeyUp", key = key }) +end + +function main:OnChar(key) + t_insert(self.inputEvents, { type = "Char", key = key }) +end + +function main:Init() + self.inputEvents = { } + + self.tree = self.TreeClass.NewTree() + + self:SetMode("LIST") + + self:LoadSettings() +end + +function main:Shutdown() + self:CallMode("Shutdown") + + self:SaveSettings() +end + +return main \ No newline at end of file diff --git a/ModParser.lua b/ModParser.lua new file mode 100644 index 00000000..303e6a73 --- /dev/null +++ b/ModParser.lua @@ -0,0 +1,545 @@ +-- List of modifier forms +local formList = { + ["^(%d+)%% increased"] = "INC", + ["^(%d+)%% reduced"] = "RED", + ["^(%d+)%% more"] = "MORE", + ["^(%d+)%% less"] = "LESS", + ["^([%+%-][%d%.]+)%%?"] = "BASE", + ["^([%+%-][%d%.]+)%%? to"] = "BASE", + ["^you gain ([%d%.]+)"] = "BASE", + ["^([%+%-]?%d+)%% chance"] = "CHANCE", + ["^([%+%-]?%d+)%% additional chance"] = "CHANCE", + ["^([%d%.]+)%% of"] = "CONV", + ["^gain ([%d%.]+)%% of"] = "CONV", + ["penetrates (%d+)%%"] = "PEN", + ["penetrates (%d+)%% of enemy"] = "PEN", + ["^([%d%.]+)%% of (.+) regenerated per second"] = "REGENPERCENT", + ["^([%d%.]+) (.+) regenerated per second"] = "REGENFLAT", +} + +-- Map of modifier names +-- '{suf}' is replaced with modifier suffix ('Base', 'Inc', 'More') +local modNameList = { + -- Attributes + ["strength"] = "str{suf}", + ["dexterity"] = "dex{suf}", + ["intelligence"] = "int{suf}", + ["strength and dexterity"] = { "str{suf}", "dex{suf}" }, + ["strength and intelligence"] = { "str{suf}", "int{suf}" }, + ["dexterity and intelligence"] = { "dex{suf}", "int{suf}" }, + ["all attributes"] = { "str{suf}", "dex{suf}", "int{suf}" }, + -- Life/mana + ["maximum life"] = "life{suf}", + ["maximum mana"] = "mana{suf}", + ["mana regeneration rate"] = "manaRegen{suf}", + ["mana cost"] = "manaCost{suf}", + ["mana cost of skills"] = "manaCost{suf}", + ["mana reserved"] = "manaReserved{suf}", + ["mana reservation"] = "manaReserved{suf}", + -- Primary defences + ["maximum energy shield"] = "energyShield{suf}", + ["energy shield recharge rate"] = "energyShieldRecharge{suf}", + ["armour"] = "armour{suf}", + ["evasion rating"] = "evasion{suf}", + ["energy shield"] = "energyShield{suf}", + ["armour and evasion"] = "armourAndEvasion{suf}", + ["armour and evasion rating"] = "armourAndEvasion{suf}", + ["evasion rating and armour"] = "armourAndEvasion{suf}", + ["armour and energy shield"] = "armourAndEnergyShield{suf}", + ["evasion and energy shield"] = "evasionAndEnergyShield{suf}", + ["defences"] = "defences{suf}", + ["global defences"] = "defences{suf}", + -- Resistances + ["fire resistance"] = "fireResist", + ["maximum fire resistance"] = "fireResistMax", + ["cold resistance"] = "coldResist", + ["maximum cold resistance"] = "coldResistMax", + ["lightning resistance"] = "lightningResist", + ["maximum lightning resistance"] = "lightningResistMax", + ["fire and cold resistances"] = { "fireResist", "coldResist" }, + ["fire and lightning resistances"] = { "fireResist", "lightningResist" }, + ["cold and lightning resistances"] = { "coldResist", "lightningResist" }, + ["elemental resistances"] = "elemResist", + ["all elemental resistances"] = "elemResist", + ["chaos resistance"] = "chaosResist", + -- Other defences + ["to dodge attacks"] = "dodgeAttack", + ["to dodge spells"] = "dodgeSpell", + ["to dodge spell damage"] = "dodgeSpell", + ["to block"] = "blockChance", + ["to block spells"] = "spellBlockChance", + ["maximum block chance"] = "blockChanceMax", + ["to avoid being shocked"] = "avoidShock", + ["to avoid being frozen"] = "avoidFrozen", + ["to avoid being chilled"] = "avoidChilled", + ["to avoid being ignited"] = "avoidIgnite", + ["to avoid elemental status ailments"] = { "avoidShock", "avoidFrozen", "avoidChilled", "avoidIgnite" }, + -- Stun modifiers + ["stun recovery"] = "stunRecovery{suf}", + ["stun threshold"] = "stunThreshold{suf}", + ["block recovery"] = "blockRecovery{suf}", + ["enemy stun threshold"] = "stunEnemyThreshold{suf}", + ["stun duration on enemies"] = "stunEnemyDuration{suf}", + -- Auras/curses + ["radius of aura skills"] = "auraRadius{suf}", + ["effect of non-curse auras you cast"] = "auraEffect{suf}", + -- Charges + ["maximum power charge"] = "powerMax", + ["maximum power charges"] = "powerMax", + ["power charge duration"] = "powerDuration{suf}", + ["maximum frenzy charge"] = "frenzyMax", + ["maximum frenzy charges"] = "frenzyMax", + ["frenzy charge duration"] = "frenzyDuration{suf}", + ["maximum endurance charge"] = "enduranceMax", + ["maximum endurance charges"] = "enduranceMax", + ["endurance charge duration"] = "enduranceDuration{suf}", + ["endurance, frenzy and power charge duration"] = { "powerDuration{suf}", "frenzyDuration{suf}", "enduranceDuration{suf}" }, + -- On hit/kill effects + ["life gained on kill"] = "lifeOnKill", + ["mana gained on kill"] = "manaOnKill", + ["life gained for each enemy hit by attacks"] = "attack_lifeOnHit", + ["life gained for each enemy hit by your attacks"] = "attack_lifeOnHit", + ["life gained for each enemy hit by spells"] = "spell_lifeOnHit", + ["life gained for each enemy hit by your spells"] = "spell_lifeOnHit", + ["mana gained for each enemy hit by attacks"] = "attack_manaOnHit", + ["mana gained for each enemy hit by your attacks"] = "attack_manaOnHit", + ["energy shield gained for each enemy hit by attacks"] = "attack_energyShieldOnHit", + ["energy shield gained for each enemy hit by your attacks"] = "attack_energyShieldOnHit", + ["life and mana gained for each enemy hit"] = { "attack_lifeOnHit", "attack_manaOnHit" }, + -- Projectile modifiers + ["pierce chance"] = "pierceChance", + ["of projectiles piercing"] = "pierceChance", + ["of arrows piercing"] = "pierceChance", + ["projectile speed"] = "projectileSpeed{suf}", + ["arrow speed"] = "bow_projectileSpeed{suf}", + -- Totem/trap/mine modifiers + ["totem placement speed"] = "totemPlacementSpeed{suf}", + ["totem life"] = "totemLife{suf}", + ["totem duration"] = "totemDuration{suf}", + ["trap throwing speed"] = "trapThrowingSpeed{suf}", + ["trap trigger radius"] = "trapTriggerRadius{suf}", + ["trap duration"] = "trapDuration{suf}", + ["cooldown recovery speed for throwing traps"] = "trapCooldownRecovery{suf}", + ["mine laying speed"] = "mineLayingSpeed{suf}", + ["mine detonation radius"] = "mineDetonationRad{suf}", + ["mine duration"] = "mineDuration{suf}", + -- Other skill modifiers + ["radius"] = "aoeRadius{suf}", + ["radius of area skills"] = "aoeRadius{suf}", + ["duration"] = "duration{suf}", + ["skill effect duration"] = "duration{suf}", + -- Buffs + ["onslaught effect"] = "onslaughtEffect{suf}", + ["fortify duration"] = "fortifyDuration{suf}", + ["effect of fortify on you"] = "fortifyEffect{suf}", + -- Basic damage types + ["damage"] = "damage{suf}", + ["physical damage"] = "physical{suf}", + ["lightning damage"] = "lightning{suf}", + ["cold damage"] = "cold{suf}", + ["fire damage"] = "fire{suf}", + ["chaos damage"] = "chaos{suf}", + ["elemental damage"] = "elem{suf}", + -- Other damage forms + ["attack damage"] = "attack_damage{suf}", + ["physical attack damage"] = "attack_physical{suf}", + ["physical weapon damage"] = "weapon_physical{suf}", + ["physical melee damage"] = "melee_physical{suf}", + ["melee physical damage"] = "melee_physical{suf}", + ["wand damage"] = "wand_damage{suf}", + ["wand physical damage"] = "wand_physical{suf}", + ["damage over time"] = "dot_damage{suf}", + ["physical damage over time"] = "dot_physical{suf}", + ["burning damage"] = "degen_fire{suf}", + -- Crit/accuracy/speed modifiers + ["critical strike chance"] = "critChance{suf}", + ["global critical strike chance"] = "global_critChance{suf}", + ["critical strike multiplier"] = "critMultiplier", + ["global critical strike multiplier"] = "critMultiplier", + ["accuracy rating"] = "accuracy{suf}", + ["attack speed"] = "attackSpeed{suf}", + ["cast speed"] = "castSpeed{suf}", + ["attack and cast speed"] = "speed{suf}", + -- Elemental status ailments + ["to shock"] = "shockChance", + ["shock chance"] = "shockChance", + ["to freeze"] = "freezeChance", + ["freeze chance"] = "freezeChance", + ["to ignite"] = "igniteChance", + ["ignite chance"] = "igniteChance", + ["to freeze, shock and ignite"] = { "freezeChance", "shockChance", "igniteChance" }, + ["shock duration on enemies"] = "shock_duration{suf}", + ["freeze duration on enemies"] = "freeze_duration{suf}", + ["chill duration on enemies"] = "chill_duration{suf}", + ["ignite duration on enemies"] = "ignite_duration{suf}", + ["duration of elemental status ailments on enemies"] = { "shock_duration{suf}", "freeze_duration{suf}", "chill_duration{suf}", "ignite_duration{suf}" }, + -- Other debuffs + ["to poison on hit"] = "poisonChance", + ["poison duration"] = "poison_duration{suf}", + ["to cause bleeding"] = "bleedChance", + ["to cause bleeding on hit"] = "bleedChance", + -- Misc modifiers + ["movement speed"] = "movementSpeed{suf}", + ["light radius"] = "lightRadius{suf}", + ["rarity of items found"] = "lootRarity{suf}", + ["quantity of items found"] = "lootQuantity{suf}", +} + +-- List of modifier namespaces +local namespaceList = { + -- Weapon types + ["with axes"] = "axe_", + ["with bows"] = "bow_", + ["with claws"] = "claw_", + ["with daggers"] = "dagger_", + ["with maces"] = "mace_", + ["with staves"] = "staff_", + ["with swords"] = "sword_", + ["with wands"] = "wand_", + ["unarmed"] = "unarmed_", + ["with one handed weapons"] = "weapon1h_", + ["with one handed melee weapons"] = "weapon1hMelee_", + ["with two handed weapons"] = "weapon2h_", + ["with two handed melee weapons"] = "weapon2hMelee_", + -- Skill types + ["spell"] = "spell_", + ["for spells"] = "spell_", + ["melee"] = "melee_", + ["with weapons"] = "weapon_", + ["weapon"] = "weapon_", + ["with poison"] = "poison_", + ["with attacks"] = "attack_", + ["projectile"] = "projectile_", + ["area"] = "aoe_", + ["mine"] = "mine_", + ["with mines"] = "mine_", + ["trap"] = "trap_", + ["with traps"] = "trap_", + ["totem"] = "totem_", + ["with totem skills"] = "totem_", + ["with lightning skills"] = "lightning_", + ["with cold skills"] = "cold_", + ["with fire skills"] = "fire_", + ["with chaos skills"] = "chaos_", + -- Other + ["from equipped shield"] = "Shield_", +} + +-- List of namespaces that appear at the start of a line +local preSpaceList = { + ["^minions have "] = "minion_", + ["^minions deal "] = "minion_", + ["^attacks used by totems have "] = "totem_", + ["^spells cast by totems have "] = "totem_", + ["^melee attacks have "] = "melee_", +} + +-- List of special namespaces +local specialSpaceList = { + -- Per charge modifiers + ["per power charge"] = "power_", + ["per frenzy charge"] = "frenzy_", + ["per endurance charge"] = "endurance_", + -- Equipment conditions + ["while holding a shield"] = "condMod_UsingShield_", + ["with shields"] = "condMod_UsingShield_", + ["while dual wielding"] = "condMod_DualWielding_", + ["while wielding a staff"] = "condMod_UsingStaff_", + -- Player status conditions + ["when on low life"] = "condMod_LowLife_", + ["while on low life"] = "condMod_LowLife_", + ["when not on low life"] = "condMod_notLowLife_", + ["while not on low life"] = "condMod_notLowLife_", + ["when on full life"] = "condMod_FullLife_", + ["when not on full life"] = "condMod_notFullLife_", + ["while you have fortify"] = "condMod_Fortify_", + ["during onslaught"] = "condMod_Onslaught_", + ["while you have onslaught"] = "condMod_Onslaught_", + ["while phasing"] = "condMod_Phasing_", + ["while using a flask"] = "condMod_UsingFlask_", + ["while on consecrated ground"] = "condMod_OnConsecratedGround_", + ["if you've attacked recently"] = "condMod_AttackedRecently_", + ["if you've cast a spell recently"] = "condMod_CastSpellRecently_", + ["if you've summoned a totem recently"] = "condMod_SummonedTotemRecently_", + ["if you've used a movement skill recently"] = "condMod_UsedMovementSkillRecently_", + ["if you detonated mines recently"] = "condMod_DetonatedMinesRecently_", + ["if you've crit in the past 8 seconds"] = "condMod_CritInPast8Sec_", + ["if energy shield recharge has started recently"] = "condMod_EnergyShieldRechargeRecently_", + -- Enemy status conditions + ["against bleeding enemies"] = "condMod_EnemyBleeding_", + ["against poisoned enemies"] = "condMod_EnemyPoisoned_", + ["against burning enemies"] = "condMod_EnemyBurning_", + ["enemies which are chilled"] = "condMod_EnemyChilled_", + ["against frozen, shocked or ignited enemies"] = "condMod_EnemyFrozenShockedIgnited_", + ["against enemies that are affected by elemental status ailments"] = "condMod_EnemyElementalStatus_", + ["against enemies that are affected by no elemental status ailments"] = "condMod_notEnemyElementalStatus_", +} + +-- List of special modifiers +local specialModList = { + -- Keystones + ["your hits can't be evaded"] = { noEvade = true }, + ["never deal critical strikes"] = { noCrit = true }, + ["no critical strike multiplier"] = { noCritMult = true }, + ["the increase to physical damage from strength applies to projectile attacks as well as melee attacks"] = { ironGrip = true }, + ["converts all evasion rating to armour%. dexterity provides no bonus to evasion rating"] = { ironReflexes = true }, + ["30%% chance to dodge attacks%. 50%% less armour and energy shield, 30%% less chance to block spells and attacks"] = { dodgeAttack = 30, armourMore = 0.5, energyShieldMore = 0.5 }, + ["maximum life becomes 1, immune to chaos damage"] = { chaosInoculation = true }, + ["deal no non%-fire damage"] = { physicalFinalMore = 0, lightningFinalMore = 0, coldFinalMore = 0, chaosFinalMore = 0 }, + -- Ascendancy notables + ["movement skills cost no mana"] = { movement_manaCostMore = 0 }, + ["projectiles have 100%% additional chance to pierce targets at the start of their movement, losing this chance as the projectile travels farther"] = { pierceChance = 100 }, + ["projectile critical strike chance increased by arrow pierce chance"] = { projectile_critChanceInc = 100 }, + ["always poison on hit while using a flask"] = { condMod_UsingFlask_poisonChance = 100 }, + ["armour received from body armour is doubled"] = { ["Body Armour_armourMore"] = 2 }, + ["gain (%d+)%% of maximum mana as extra maximum energy shield"] = function(num) return { manaGainAsES = num } end, + ["you have fortify"] = { cond_Fortify = true }, + -- Special node types + ["(%d+)%% additional block chance with staves"] = function(num) return { condMod_UsingStaff_blockChance = num } end, + ["(%d+)%% additional block chance with shields"] = function(num) return { condMod_UsingShield_blockChance = num } end, + ["(%d+)%% additional block chance while dual wielding"] = function(num) return { condMod_DualWielding_blockChance = num } end, + ["(%d+)%% faster start of energy shield recharge"] = function(num) return { energyShieldRechargeFaster = num } end, + ["(%d+)%% additional block chance while dual wielding or holding a shield"] = function(num) return { condMod_DualWielding_blockChance = num, condMod_UsingShield_blockChance = num } end, + -- Other modifiers + ["adds (%d+)%-(%d+) (%a+) damage ?t?o? ?a?t?t?a?c?k?s?"] = function(_, min, max, type) local pre = "attack_"..type return { [pre.."Min"] = tonumber(min), [pre.."Max"] = tonumber(max) } end, + ["adds (%d+)%-(%d+) (%a+) damage to attacks with bows"] = function(_, min, max, type) local pre = "bow_"..type return { [pre.."Min"] = tonumber(min), [pre.."Max"] = tonumber(max) } end, + ["adds (%d+)%-(%d+) (%a+) damage to spells"] = function(_, min, max, type) local pre = "spell_"..type return { [pre.."Min"] = tonumber(min), [pre.."Max"] = tonumber(max) } end, + ["cannot be shocked"] = { avoidShock = 100 }, + ["cannot be frozen"] = { avoidFreeze = 100 }, + ["cannot be chilled"] = { avoidChill = 100 }, + ["cannot be ignited"] = { avoidIgnite = 100 }, + ["cannot be stunned"] = { stunImmunity = true }, + ["deal no physical damage"] = { physicalFinalMore = 0 }, + ["iron will"] = { ironWill = true }, + ["extra gore"] = { }, + -- Special item local modifiers + ["no physical damage"] = { weaponNoPhysical = true }, + ["all attacks with this weapon are critical strikes"] = { weaponAlwaysCrit = true }, + ["hits can't be evaded"] = { weaponX_noEvade = true }, + ["no block chance"] = { shieldNoBlock = true }, + ["has 1 socket"] = { }, + ["socketed gems have (.+)"] = { }, + ["socketed gems are Supported by (.+)"] = { }, + ["+(%d) to level of socketed (%a+) gems"] = { }, + ["grants level (%d+) (.+) skill"] = { }, + -- Unique item modifiers + ["projectile damage increased by arrow pierce chance"] = { drillneck = true }, +} + +-- Special lookups used for various modifier forms +local convTypes = { + ["as extra lightning damage"] = "GainAslightning", + ["added as lightning damage"] = "GainAslightning", + ["as extra cold damage"] = "GainAscold", + ["added as cold damage"] = "GainAscold", + ["as extra fire damage"] = "GainAsfire", + ["added as fire damage"] = "GainAsfire", + ["as extra chaos damage"] = "GainAschaos", + ["added as chaos damage"] = "GainAschaos", + ["converted to lightning damage"] = "ConvertTolightning", + ["converted to cold damage"] = "ConvertTocold", + ["converted to fire damage"] = "ConvertTofire", + ["converted to chaos damage"] = "ConvertTochaos", +} +local penTypes = { + ["lightning resistance"] = "lightningPen", + ["cold resistance"] = "coldPen", + ["fire resistance"] = "firePen", + ["elemental resistance"] = "elemPen", + ["elemental resistances"] = "elemPen", +} +local regenTypes = { + ["life"] = "lifeRegen{suf}", + ["maximum life"] = "lifeRegen{suf}", + ["mana"] = "manaRegen{suf}", + ["energyShield"] = "energyShieldRegen{suf}", +} + +-- Build active skill name lookup +local skillNameList = { } +for skillName, data in pairs(data.gems) do + if not data.support then + skillNameList[skillName:lower()] = "skill:" .. skillName .. "_" + end +end + +local function getSimpleConv(src, dst, factor) + return function(mods, allMods, data) + if mods and mods[src] then + mod.listMerge(allMods, dst, mods[src] * factor) + mods[src] = nil + end + end +end +local function getMatchConv(others, dst) + return function(mods, allMods, data) + if mods then + for k, v in pairs(mods) do + for _, other in pairs(others) do + if k:match(other) then + mod.listMerge(allMods, k:gsub(other, dst), v) + mods[k] = nil + end + end + end + end + end +end +local function getPerStat(dst, stat, factor) + return function(mods, allMods, data) + if mods then + data[stat] = (data[stat] or 0) + (mods[stat] or 0) + else + mod.listMerge(allMods, dst, math.floor(data[stat] * factor + 0.5)) + end + end +end +-- List of radius jewel functions +local jewelFuncs = { + ["Strength from Passives in Radius is Transformed to Dexterity"] = getSimpleConv("strBase", "dexBase", 1), + ["Dexterity from Passives in Radius is Transformed to Strength"] = getSimpleConv("dexBase", "strBase", 1), + ["Strength from Passives in Radius is Transformed to Intelligence"] = getSimpleConv("strBase", "intBase", 1), + ["Intelligence from Passives in Radius is Transformed to Strength"] = getSimpleConv("intBase", "strBase", 1), + ["Dexterity from Passives in Radius is Transformed to Intelligence"] = getSimpleConv("dexBase", "intBase", 1), + ["Intelligence from Passives in Radius is Transformed to Dexterity"] = getSimpleConv("intBase", "dexBase", 1), + ["Increases and Reductions to Life in Radius are Transformed to apply to Energy Shield"] = getSimpleConv("lifeInc", "energyShieldInc", 1), + ["Increases and Reductions to Energy Shield in Radius are Transformed to apply to Armour at 200% of their value"] = getSimpleConv("energyShieldInc", "armourInc", 2), + ["Increases and Reductions to Life in Radius are Transformted to apply to Mana at 200% of their value"] = getSimpleConv("lifeInc", "manaInc", 2), + ["Increases and Reductions to Physical Damage in Radius are transformed to apply to Cold Damage"] = getMatchConv({"physicalInc"}, "coldInc"), + ["Increases and Reductions to Cold Damage in Radius are transformed to apply to Physical Damage"] = getMatchConv({"coldInc"}, "physicalInc"), + ["Increases and Reductions to other Damage Types in Radius are Transformed to apply to Fire Damage"] = getMatchConv({"physicalInc","coldInc","lightningInc","chaosInc"}, "fireInc"), + ["Melee and Melee Weapon Type Modifiers in Radius are Transformed to Bow Modifiers"] = getMatchConv({"melee_","axe_","claw_","dagger_","mace_","staff_","sword_"}, "bow_"), + ["Adds 1 to maximum Life per 3 Intelligence in Radius"] = getPerStat("lifeBase", "intBase", 1 / 3), + ["1% increased Evasion Rating per 3 Dexterity Allocated in Radius"] = getPerStat("evasionInc", "dexBase", 1 / 3), + ["1% increased Claw Physical Damage per 3 Dexterity Allocated in Radius"] = getPerStat("claw_physicalInc", "dexBase", 1 / 3), + ["1% increased Melee Physical Damage while Unarmed per 3 Dexterity Allocated in Radius"] = getPerStat("unarmed_physicalInc", "dexBase", 1 / 3), + ["3% increased Totem Life per 10 Strength in Radius"] = getPerStat("totemLifeInc", "strBase", 3 / 10), + ["Adds 1 maximum Lightning Damage to Attacks per 1 Dexterity Allocated in Radius"] = getPerStat("attack_lightningMax", "dexBase", 1), + ["5% increased Chaos damage per 10 Intelligence from Allocated Passives in Radius"] = getPerStat("chaosInc", "intBase", 5 / 10), + ["Dexterity and Intelligence from passives in Radius count towards Strength Melee Damage bonus"] = function(mods, allMods, data) + if mods then + data.dexBase = (data.dexBase or 0) + (mods.dexBase or 0) + data.intBase = (data.intBase or 0) + (mods.intBase or 0) + else + mod.listMerge(allMods, "dexIntToMeleeBonus", data.dexBase + data.intBase) + end + end, +} + +-- Scan a line for the earliest and longest match from the pattern list +-- If a match is found, returns the corresponding value from the pattern table, plus the remainder of the line and a table of captures +local function scan(line, patternList, plain) + local bestIndex, bestEndIndex + local bestMatch = { nil, line, nil } + for pattern, patternVal in pairs(patternList) do + local index, endIndex, cap1, cap2, cap3, cap4, cap5 = line:lower():find(pattern, 1, plain) + if index and (not bestIndex or index < bestIndex or (index == bestIndex and endIndex > bestEndIndex)) then + bestIndex = index + bestEndIndex = endIndex + bestMatch = { patternVal, line:sub(1, index - 1)..line:sub(endIndex + 1, -1), { cap1, cap2, cap3, cap4, cap5 } } + end + end + return bestMatch[1], bestMatch[2], bestMatch[3] +end + +return function(line) + -- Check if this is a special modifier + local specialMod, specialLine, cap = scan(line, specialModList) + if specialMod and #specialLine == 0 then + if type(specialMod) == "function" then + return specialMod(tonumber(cap[1]), unpack(cap)) + else + return copyTable(specialMod) + end + end + if jewelFuncs[line] then + return { jewelFunc = jewelFuncs[line] } + end + + -- Check for a namespace at the start of the line + local space + space, line = scan(line, preSpaceList) + + -- Scan for modifier form + local modForm, formCap + modForm, line, formCap = scan(line, formList) + if not modForm then + return + end + local num = tonumber(formCap[1]) + + -- Check for special namespaces (per-charge, conditionals) + local specialSpace + specialSpace, line = scan(line, specialSpaceList, true) + + -- Scan for modifier name + local modName + modName, line = scan(line, modNameList, true) + if not modName and line:match("%S") then + return { }, line + end + + -- Scan for skill name + local skillSpace + skillSpace, line = scan(line, skillNameList, true) + + -- Scan for namespace if one hasn't been found already + if not space then + space, line = scan(line, namespaceList, true) + end + + -- Find modifier value and suffix according to form + local val, suffix + if modForm == "INC" then + val = num + suffix = "Inc" + elseif modForm == "RED" then + val = -num + suffix = "Inc" + elseif modForm == "MORE" then + val = 1 + num / 100 + suffix = "More" + elseif modForm == "LESS" then + val = 1 - num / 100 + suffix = "More" + elseif modForm == "BASE" then + val = num + suffix = "Base" + elseif modForm == "CHANCE" then + val = num + elseif modForm == "CONV" then + val = num + suffix, line = scan(line, convTypes, true) + if not suffix then + return { }, line + end + elseif modForm == "PEN" then + val = num + modName, line = scan(line, penTypes, true) + if not modName then + return { }, line + end + elseif modForm == "REGENPERCENT" then + val = num + suffix = "Percent" + modName = regenTypes[formCap[2]:lower()] + if not modName then + return { }, line + end + elseif modForm == "REGENFLAT" then + val = num + suffix = "Base" + modName = regenTypes[formCap[2]:lower()] + if not modName then + return { }, line + end + end + + -- Generate modifier list + local nameList = modName or "" + local modList = { } + for i, name in ipairs(type(nameList) == "table" and nameList or { nameList }) do + modList[(skillSpace or "") .. (specialSpace or "") .. (space or "") .. name:gsub("{suf}", suffix or "")] = val + end + return modList, line:match("%S") and line +end \ No newline at end of file diff --git a/ModTools.lua b/ModTools.lua new file mode 100644 index 00000000..646d5429 --- /dev/null +++ b/ModTools.lua @@ -0,0 +1,155 @@ + +local t_insert = table.insert + +mod = { } + +mod.parseMod = LoadModule("ModParser") + +-- Break modifier name into namespace and mod name +local spaceLookup = { } +function mod.getSpaceName(modName) + if not spaceLookup[modName] then + local space, mod = modName:match("^([^_]+)_(.+)$") + if not space then + space = "global" + mod = modName + end + spaceLookup[modName] = { space, mod } + return space, mod + end + return unpack(spaceLookup[modName]) +end + +-- Extract condition name from modifier name +local condLookup = { } +function mod.getCondName(modName) + if not condLookup[modName] then + local isNot, condName, mod = modName:match("^(n?o?t?)(%w+)_(.+)$") + isNot = (isNot == "not") + condLookup[modName] = { isNot, condName, mod } + return isNot, condName, mod + end + return unpack(condLookup[modName]) +end + +-- Magic table to check if a modifier is multiplicative (contains 'More' in the modifier name) +mod.isModMult = { } +mod.isModMult.__index = function(t, modName) + local val = (modName:match("More") ~= nil) + t[modName] = val + return val +end +setmetatable(mod.isModMult, mod.isModMult) + +-- Merge modifier with existing mod list, respecting additivity/multiplicativity +function mod.listMerge(modList, modName, modVal) + if modList[modName] then + if type(modVal) == "boolean" then + modList[modName] = modList[modName] or modVal + elseif type(modVal) == "function" then + local orig = modList[modName] + modList[modName] = function(...) orig(...) modVal(...) end + elseif mod.isModMult[modName] then + modList[modName] = modList[modName] * modVal + else + modList[modName] = modList[modName] + modVal + end + else + modList[modName] = modVal + end +end + +-- Unmerge modifier from existing mod list, respecting additivity/multiplicativity +function mod.listUnmerge(modList, modName, modVal) + if type(modVal) == "boolean" then + if modVal == true then + modList[modName] = false + end + elseif type(modVal) == "string" then + modList[modName] = nil + elseif mod.isModMult[modName] then + if modVal == 0 then + modList[modName] = 1 + else + modList[modName] = (modList[modName] or 1) / modVal + end + else + modList[modName] = (modList[modName] or 0) - modVal + end +end + +-- Merge modifier with mod database +function mod.dbMerge(modDB, spaceName, modName, modVal) + if not spaceName then + spaceName, modName = mod.getSpaceName(modName) + elseif spaceName == "" then + spaceName = "global" + end + if not modDB[spaceName] then + modDB[spaceName] = { } + end + mod.listMerge(modDB[spaceName], modName, modVal) +end + +-- Unmerge modifier from mod database +function mod.dbUnmerge(modDB, spaceName, modName, modVal) + if not spaceName then + spaceName, modName = mod.getSpaceName(modName) + elseif spaceName == "" then + spaceName = "global" + end + if not modDB[spaceName] then + modDB[spaceName] = { } + end + mod.listUnmerge(modDB[spaceName], modName, modVal) +end + +-- Merge modifier list with mod database +function mod.dbMergeList(modDB, modList) + for k, modVal in pairs(modList) do + local spaceName, modName = mod.getSpaceName(k) + if not modDB[spaceName] then + modDB[spaceName] = { } + end + mod.listMerge(modDB[spaceName], modName, modVal) + end +end + +-- Unmerge modifier list from mod database +function mod.dbUnmergeList(modDB, modList) + for k, modVal in pairs(modList) do + local spaceName, modName = mod.getSpaceName(k) + if not modDB[spaceName] then + modDB[spaceName] = { } + end + mod.listUnmerge(modDB[spaceName], modName, modVal) + end +end + +-- Print modifier list to the console +function mod.listPrint(modList, tab) + local names = { } + for k in pairs(modList) do + if type(k) == "string" then + t_insert(names, k) + end + end + table.sort(names) + for _, name in pairs(names) do + ConPrintf("%s%s = %s", string.rep("\t", tab or 0), name, modList[name]) + end +end + +-- Print modifier database to the console +function mod.dbPrint(modDB) + local spaceNames = { } + for k in pairs(modDB) do + t_insert(spaceNames, k) + end + table.sort(spaceNames) + for _, spaceName in pairs(spaceNames) do + ConPrintf("%s = {", spaceName) + mod.listPrint(modDB[spaceName], 1) + ConPrintf("},") + end +end \ No newline at end of file diff --git a/PathOfBuilding.sln b/PathOfBuilding.sln new file mode 100644 index 00000000..6885df9e --- /dev/null +++ b/PathOfBuilding.sln @@ -0,0 +1,60 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AE7B8DC6-833A-4817-915D-AAB9B8F17C1B}" + ProjectSection(SolutionItems) = preProject + _gemparse.lua = _gemparse.lua + Build.lua = Build.lua + Calcs.lua = Calcs.lua + CalcsControl.lua = CalcsControl.lua + CalcsView.lua = CalcsView.lua + Common.lua = Common.lua + Data.lua = Data.lua + Items.lua = Items.lua + Launch.lua = Launch.lua + List.lua = List.lua + Main.lua = Main.lua + ModParser.lua = ModParser.lua + ModTools.lua = ModTools.lua + Spec.lua = Spec.lua + Tree.lua = Tree.lua + TreeView.lua = TreeView.lua + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gem DB", "Gem DB", "{EE9D06F5-7310-4567-AB18-6923BCF0A2A1}" + ProjectSection(SolutionItems) = preProject + gems\act_dex.lua = gems\act_dex.lua + gems\act_int.lua = gems\act_int.lua + gems\act_str.lua = gems\act_str.lua + gems\sup_dex.lua = gems\sup_dex.lua + gems\sup_int.lua = gems\sup_int.lua + gems\sup_str.lua = gems\sup_str.lua + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Item DB", "Item DB", "{5BCB69A7-EFE8-4C72-B5E3-DF2C1E227290}" + ProjectSection(SolutionItems) = preProject + Items\axe.lua = Items\axe.lua + Items\body.lua = Items\body.lua + Items\boots.lua = Items\boots.lua + Items\bow.lua = Items\bow.lua + Items\claw.lua = Items\claw.lua + Items\dagger.lua = Items\dagger.lua + Items\glove.lua = Items\glove.lua + Items\helm.lua = Items\helm.lua + Items\mace.lua = Items\mace.lua + Items\misc.lua = Items\misc.lua + Items\shield.lua = Items\shield.lua + Items\staff.lua = Items\staff.lua + Items\sword.lua = Items\sword.lua + Items\wand.lua = Items\wand.lua + EndProjectSection +EndProject +Global + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {EE9D06F5-7310-4567-AB18-6923BCF0A2A1} = {AE7B8DC6-833A-4817-915D-AAB9B8F17C1B} + {5BCB69A7-EFE8-4C72-B5E3-DF2C1E227290} = {AE7B8DC6-833A-4817-915D-AAB9B8F17C1B} + EndGlobalSection +EndGlobal diff --git a/Spec.lua b/Spec.lua new file mode 100644 index 00000000..80532bae --- /dev/null +++ b/Spec.lua @@ -0,0 +1,310 @@ +local launch, cfg, main = ... + +local pairs = pairs +local ipairs = ipairs +local m_min = math.min +local m_max = math.max +local m_floor = math.floor +local t_insert = table.insert + +local SpecClass = { } +SpecClass.__index = SpecClass + +local function buildPathFromNode(root) + root.pathDist = 0 + root.path = { } + local queue = { root } + local o, i = 1, 2 + while o < i do + local node = queue[o] + o = o + 1 + local curDist = node.pathDist + 1 + for _, other in ipairs(node.linked) do + if other.type ~= "class" and other.type ~= "ascendClass" and other.pathDist > curDist and (node.ascendancyName == other.ascendancyName or (curDist == 1 and not other.ascendancyName)) then + other.pathDist = curDist + other.path = wipeTable(other.path) + other.path[1] = other + for i, n in ipairs(node.path) do + other.path[i+1] = n + end + queue[i] = other + i = i + 1 + end + end + end +end +function SpecClass:BuildAllPaths() + for id, node in pairs(self.nodes) do + node.pathDist = node.alloc and 0 or 1000 + node.path = nil + end + for id, node in pairs(self.allocNodes) do + buildPathFromNode(node) + end +end + +local function findStart(node, visited, noAscend) + node.visited = true + t_insert(visited, node) + for _, other in ipairs(node.linked) do + if other.alloc and (other.type == "class" or other.type == "ascendClass" or (not other.visited and findStart(other, visited, noAscend))) then + if not noAscend or other.type ~= "ascendClass" then + return true + end + end + end +end +function SpecClass:BuildAllDepends() + local visited = { } + for id, node in pairs(self.nodes) do + node.depends = wipeTable(node.depends) + if node.alloc then + node.depends[1] = node + node.visited = true + local anyStartFound = (node.type == "class" or node.type == "ascendClass") + for _, other in ipairs(node.linked) do + if other.alloc then + if other.type == "class" or other.type == "ascendClass" then + anyStartFound = true + elseif findStart(other, visited) then + anyStartFound = true + for i, n in ipairs(visited) do + n.visited = false + visited[i] = nil + end + else + for i, n in ipairs(visited) do + t_insert(node.depends, n) + n.visited = false + visited[i] = nil + end + end + end + end + node.visited = false + if not anyStartFound then + for _, depNode in ipairs(node.depends) do + depNode.alloc = false + self.allocNodes[depNode.id] = nil + end + end + end + end +end + +function SpecClass:AllocNode(node, altPath) + if not node.path then + return + end + for _, pathNode in ipairs(altPath or node.path) do + pathNode.alloc = true + self.allocNodes[pathNode.id] = pathNode + buildPathFromNode(pathNode) + end + if node.isMultipleChoiceOption then + local parent = node.linked[1] + for _, optNode in ipairs(parent.linked) do + if optNode.isMultipleChoiceOption and optNode.alloc and optNode ~= node then + optNode.alloc = false + self.allocNodes[optNode.id] = nil + self:BuildAllPaths() + end + end + end + self:BuildAllDepends() +end +function SpecClass:DeallocNode(node) + for _, depNode in ipairs(node.depends) do + depNode.alloc = false + self.allocNodes[depNode.id] = nil + end + self:BuildAllDepends() + self:BuildAllPaths() +end + +function SpecClass:CountAllocNodes() + local used, ascUsed = 0, 0 + for _, node in pairs(self.allocNodes) do + if node.type ~= "class" and node.type ~= "ascendClass" then + if node.ascendancyName then + if not node.isMultipleChoiceOption then + ascUsed = ascUsed + 1 + end + else + used = used + 1 + end + end + end + return used, ascUsed +end + +function SpecClass:ResetNodes() + for id, node in pairs(self.nodes) do + if node.type ~= "class" and node.type ~= "ascendClass" then + node.alloc = false + self.allocNodes[id] = nil + end + end +end + +function SpecClass:IsClassConnected(classId) + for _, other in ipairs(self.nodes[self.tree.classes[classId].startNodeId].linked) do + if other.alloc then + other.visited = true + local visited = { } + local found = findStart(other, visited, true) + for i, n in ipairs(visited) do + n.visited = false + end + other.visited = false + if found then + return true + end + end + end + return false +end + +function SpecClass:SelectClass(classId) + if self.curClassId then + local oldStartNodeId = self.tree.classes[self.curClassId].startNodeId + self.nodes[oldStartNodeId].alloc = false + self.allocNodes[oldStartNodeId] = nil + end + self.curClassId = classId + local class = self.tree.classes[classId] + local startNode = self.nodes[class.startNodeId] + startNode.alloc = true + self.allocNodes[startNode.id] = startNode + self:SelectAscendClass(0) +end +function SpecClass:SelectAscendClass(ascendClassId) + self.curAscendClassId = ascendClassId + local ascendClass = self.tree.classes[self.curClassId].classes[tostring(ascendClassId)] or { name = "" } + for id, node in pairs(self.allocNodes) do + if node.ascendancyName and node.ascendancyName ~= ascendClass.name then + node.alloc = false + self.allocNodes[id] = nil + end + end + if ascendClass.startNodeId then + local startNode = self.nodes[ascendClass.startNodeId] + startNode.alloc = true + self.allocNodes[startNode.id] = startNode + end + self:BuildAllDepends() + self:BuildAllPaths() +end + +function SpecClass:DecodeURL(url) + self:ResetNodes() + local b = common.base64.decode(url:gsub("^.+/",""):gsub("-","+"):gsub("_","/")) + local ver = b:byte(4) + local classId = b:byte(5) + local ascendClassId = (ver >= 4) and b:byte(6) or 0 + self:SelectClass(classId) + for i = (ver >= 4) and 8 or 7, #b-1, 2 do + local id = b:byte(i) * 256 + b:byte(i + 1) + local node = self.nodes[id] + if node then + node.alloc = true + self.allocNodes[id] = node + if ascendClassId == 0 and node.ascendancyName then + ascendClassId = self.tree.ascendNameMap[node.ascendancyName].ascendClassId + end + end + end + self:SelectAscendClass(ascendClassId) +end +function SpecClass:EncodeURL(prefix) + local a = { 0, 0, 0, 4, self.curClassId, self.curAscendClassId, 0 } + for id, node in pairs(self.allocNodes) do + if node.type ~= "class" and node.type ~= "ascendClass" then + t_insert(a, m_floor(id / 256)) + t_insert(a, id % 256) + end + end + return (prefix or "")..common.base64.encode(string.char(unpack(a))):gsub("+","-"):gsub("/","_") +end + +function SpecClass:AddUndoState(noClearRedo) + t_insert(self.undo, 1, self:EncodeURL()) + self.undo[102] = nil + self.modFlag = true + self.buildFlag = true + if not noClearRedo then + self.redo = { } + end +end +function SpecClass:Undo() + if self.undo[2] then + t_insert(self.redo, 1, table.remove(self.undo, 1)) + self:DecodeURL(table.remove(self.undo, 1)) + self:AddUndoState(true) + self.modFlag = true + self.buildFlag = true + end +end +function SpecClass:Redo() + if self.redo[1] then + self:DecodeURL(table.remove(self. redo, 1)) + self:AddUndoState(true) + self.modFlag = true + self.buildFlag = true + end +end + +function SpecClass:Load(xml, dbFileName) + for _, node in pairs(xml) do + if type(node) == "table" then + if node.elem == "URL" then + if type(node[1]) ~= "string" then + launch:ShowErrMsg("^1Error parsing '%s': 'URL' element missing content", fileName) + return true + end + self:DecodeURL(node[1]) + self.undo = { node[1] } + self.redo = { } + end + end + end + self.modFlag = false +end +function SpecClass:Save(xml) + t_insert(xml, { + elem = "URL", + [1] = self:EncodeURL("https://www.pathofexile.com/passive-skill-tree/") + }) + self.modFlag = false +end + +function SpecClass.NewSpec(tree) + local self = setmetatable({}, SpecClass) + + self.tree = tree + + self.nodes = { } + for _, treeNode in ipairs(tree.nodes) do + self.nodes[treeNode.id] = setmetatable({ + rsq = treeNode.overlay and treeNode.overlay.rsq, + size = treeNode.overlay and treeNode.overlay.size, + linked = { } + }, { __index = treeNode }) + end + for id, node in pairs(self.nodes) do + for _, otherId in ipairs(node.linkedId) do + t_insert(node.linked, self.nodes[otherId]) + end + end + + self.allocNodes = { } + + self.undo = { } + self.redo = { } + + self:SelectClass(0) + + return self +end + +return SpecClass \ No newline at end of file diff --git a/Tree.lua b/Tree.lua new file mode 100644 index 00000000..f0fb14fd --- /dev/null +++ b/Tree.lua @@ -0,0 +1,338 @@ +local launch, cfg, main = ... + +local pairs = pairs +local ipairs = ipairs +local m_min = math.min +local m_max = math.max +local m_pi = math.pi +local m_sin = math.sin +local m_cos = math.cos +local m_tan = math.tan +local m_sqrt = math.sqrt +local t_insert = table.insert + +local function cacheImage(imgName, url) + local imgFile = io.open(imgName, "r") + if imgFile then + imgFile:close() + else + ConPrintf("Downloading '%s'...", imgName) + imgFile = io.open(imgName, "wb") + local easy = common.curl.easy() + easy:setopt_url(url) + easy:setopt_writefunction(imgFile) + easy:perform() + easy:close() + imgFile:close() + end +end + +local TreeClass = { } +TreeClass.__index = TreeClass + +function TreeClass:BuildConnector(node1, node2) + local conn = { + ascendancyName = node1.ascendancyName, + nodeId1 = node1.id, + nodeId2 = node2.id, + c = { } + } + if node1.g == node2.g and node1.o == node2.o then + conn.type = "Orbit" .. node1.o + if node1.angle > node2.angle then + node1, node2 = node2, node1 + end + local span = node2.angle - node1.angle + if span > m_pi then + node1, node2 = node2, node1 + span = m_pi * 2 - span + end + local clipAngle = m_pi / 4 - span / 2 + local p = 1 - m_max(m_tan(clipAngle), 0) + local angle = node1.angle - clipAngle + local norm, act = { }, { } + for tbl, state in pairs({[norm] = "Normal", [act] = "Active"}) do + local art = self.assets[conn.type..state] + local size = art.width * 2 * 1.33 + local oX, oY = size * m_sqrt(2) * m_sin(angle + m_pi/4), size * m_sqrt(2) * -m_cos(angle + m_pi/4) + local cX, cY = node1.group.x + oX, node1.group.y + oY + tbl[1], tbl[2] = node1.group.x, node1.group.y + tbl[3], tbl[4] = cX + (size * m_sin(angle) - oX) * p, cY + (size * -m_cos(angle) - oY) * p + tbl[5], tbl[6] = cX, cY + tbl[7], tbl[8] = cX + (size * m_cos(angle) - oX) * p, cY + (size * m_sin(angle) - oY) * p + end + conn.vert = { Normal = norm, Intermediate = norm, Active = act } + conn.c[9], conn.c[10] = 1, 1 + conn.c[11], conn.c[12] = 0, p + conn.c[13], conn.c[14] = 0, 0 + conn.c[15], conn.c[16] = p, 0 + else + conn.type = "LineConnector" + local art = self.assets.LineConnectorNormal + local vX, vY = node2.x - node1.x, node2.y - node1.y + local dist = m_sqrt(vX * vX + vY * vY) + local scale = art.height * 1.33 / dist + local nX, nY = vX * scale, vY * scale + local endS = dist / (art.width * 1.33) + conn[1], conn[2] = node1.x - nY, node1.y + nX + conn[3], conn[4] = node1.x + nY, node1.y - nX + conn[5], conn[6] = node2.x + nY, node2.y - nX + conn[7], conn[8] = node2.x - nY, node2.y + nX + conn.vert = { Normal = conn, Intermediate = conn, Active = conn } + conn.c[9], conn.c[10] = 0, 1 + conn.c[11], conn.c[12] = 0, 0 + conn.c[13], conn.c[14] = endS, 0 + conn.c[15], conn.c[16] = endS, 1 + end + return conn +end + +function TreeClass.NewTree() + os.execute("mkdir Data") + + ConPrintf("Loading JSON...") + local treeText, classText + local treeFile = io.open("Data/tree.json", "r") + local classFile = io.open("Data/classes.json", "r") + if treeFile and classFile then + treeText = treeFile:read("*a") + treeFile:close() + classText = classFile:read("*a") + classFile:close() + else + if treeFile then + treeFile:close() + elseif classFile then + classFile:close() + end + ConPrintf("Downloading JSON...") + local page = "" + local easy = common.curl.easy() + easy:setopt_url("https://www.pathofexile.com/passive-skill-tree/") + easy:setopt_writefunction(function(data) + page = page..data + return true + end) + easy:perform() + easy:close() + treeText = page:match("var passiveSkillTreeData = (%b{})") + treeFile = io.open("Data/tree.json", "w") + treeFile:write(treeText) + treeFile:close() + classText = page:match("ascClasses: (%b{})") + classFile = io.open("Data/classes.json", "w") + classFile:write(classText) + classFile:close() + end + local self = common.json.decode(treeText) + self.classes = { } + for id, data in pairs(common.json.decode(classText)) do + self.classes[tonumber(id)] = data + data.classes["0"] = { name = "None "} + end + setmetatable(self, TreeClass) + + self.size = m_min(self.max_x - self.min_x, self.max_y - self.min_y) * 1.1 + + ConPrintf("Loading assets...") + for name, data in pairs(self.assets) do + local imgName = "Data/"..name..".png" + cacheImage(imgName, data["0.3835"] or data["1"]) + data.handle = NewImageHandle() + data.handle:Load(imgName) + data.width, data.height = data.handle:ImageSize() + end + + local spriteMap = { } + local spriteSheets = { } + for type, data in pairs(self.skillSprites) do + local maxZoom = data[#data] + local sheet = spriteSheets[maxZoom.filename] + if not sheet then + sheet = { } + local imgName = "Data/"..maxZoom.filename + cacheImage(imgName, self.imageRoot.."build-gen/passive-skill-sprite/"..maxZoom.filename) + sheet.handle = NewImageHandle() + sheet.handle:Load(imgName, "CLAMP") + sheet.width, sheet.height = sheet.handle:ImageSize() + spriteSheets[maxZoom.filename] = sheet + end + for name, coords in pairs(maxZoom.coords) do + if not spriteMap[name] then + spriteMap[name] = { } + end + spriteMap[name][type] = { + handle = sheet.handle, + width = coords.w, + height = coords.h, + [1] = coords.x / sheet.width, + [2] = coords.y / sheet.height, + [3] = (coords.x + coords.w) / sheet.width, + [4] = (coords.y + coords.h) / sheet.height + } + end + end + + local nodeOverlay = { + normal = { + alloc = "PSSkillFrameActive", + path = "PSSkillFrameHighlighted", + unalloc = "PSSkillFrame", + allocAscend = "PassiveSkillScreenAscendancyFrameSmallAllocated", + pathAscend = "PassiveSkillScreenAscendancyFrameSmallCanAllocate", + unallocAscend = "PassiveSkillScreenAscendancyFrameSmallNormal" + }, + notable = { + alloc = "NotableFrameAllocated", + path = "NotableFrameCanAllocate", + unalloc = "NotableFrameUnallocated", + allocAscend = "PassiveSkillScreenAscendancyFrameLargeAllocated", + pathAscend = "PassiveSkillScreenAscendancyFrameLargeCanAllocate", + unallocAscend = "PassiveSkillScreenAscendancyFrameLargeNormal" + }, + keystone = { + alloc = "KeystoneFrameAllocated", + path = "KeystoneFrameCanAllocate", + unalloc = "KeystoneFrameUnallocated" + }, + socket = { + alloc = "JewelFrameAllocated", + path = "JewelFrameCanAllocate", + unalloc = "JewelFrameUnallocated" + } + } + for type, data in pairs(nodeOverlay) do + local size = self.assets[data.unalloc].width * 1.33 + data.size = size + data.rsq = size * size + end + + ConPrintf("Building nodes...") + local nodeMap = { } + local orbitMult = { [0] = 0, m_pi / 3, m_pi / 6, m_pi / 6, m_pi / 20 } + local orbitDist = { [0] = 0, 82, 162, 335, 493 } + for _, node in ipairs(self.nodes) do + nodeMap[node.id] = node + if node.spc[1] then + node.type = "class" + elseif node.isAscendancyStart then + node.type = "ascendClass" + elseif node.m then + node.type = "mastery" + elseif node.isJewelSocket then + node.type = "socket" + elseif node.ks then + node.type = "keystone" + elseif node["not"] then + node.type = "notable" + else + node.type = "normal" + end + node.sprites = spriteMap[node.icon] + node.overlay = nodeOverlay[node.type] + node.linkedId = { } + + local group = self.groups[tostring(node.g)] + group.ascendancyName = node.ascendancyName + if node.isAscendancyStart then + group.isAscendancyStart = true + end + node.group = group + node.angle = node.oidx * orbitMult[node.o] + local dist = orbitDist[node.o] + node.x = group.x + m_sin(node.angle) * dist + node.y = group.y - m_cos(node.angle) * dist + + node.mods = { } + node.modKey = "" + local i = 1 + while node.sd[i] do + local line = node.sd[i] + local list, extra + if line:match("\n") then + list, extra = mod.parseMod(line:gsub("\n", " ")) + if list and not extra then + node.sd[i] = line:gsub("\n", " ") + else + table.remove(node.sd, i) + local si = i + for subLine in line:gmatch("[^\n]+") do + table.insert(node.sd, si, subLine) + si = si + 1 + end + list, extra = mod.parseMod(node.sd[i]) + end + else + list, extra = mod.parseMod(line) + end + if not list then + node.unknown = true + elseif extra then + node.extra = true + else + for k, v in pairs(list) do + node.modKey = node.modKey..k.."="..tostring(v).."," + end + end + node.mods[i] = { list = list, extra = extra } + i = i + 1 + end + end + + ConPrintf("Building connections...") + self.conn = { } + for _, node in ipairs(self.nodes) do + for _, otherId in ipairs(node.out) do + local other = nodeMap[otherId] + t_insert(node.linkedId, otherId) + t_insert(other.linkedId, node.id) + if node.type ~= "class" and other.type ~= "class" and node.ascendancyName == other.ascendancyName then + t_insert(self.conn, self:BuildConnector(node, other)) + end + end + end + + self.classNameMap = { } + self.ascendNameMap = { ["None"] = { classId = 0, ascendClassId = 0 } } + for classId, class in pairs(self.classes) do + self.classNameMap[class.name] = classId + for ascendClassId, ascendClass in pairs(class.classes) do + self.ascendNameMap[ascendClass.name] = { + classId = classId, + ascendClassId = ascendClassId + } + end + end + + local classArt = { + [0] = "centerscion", + [1] = "centermarauder", + [2] = "centerranger", + [3] = "centerwitch", + [4] = "centerduelist", + [5] = "centertemplar", + [6] = "centershadow" + } + for _, node in ipairs(self.nodes) do + if node.type == "class" then + local class = self.classes[node.spc[1]] + class.startNodeId = node.id + node.startArt = classArt[node.spc[1]] + for _, otherId in ipairs(node.linkedId) do + local other = nodeMap[otherId] + if other.type == "ascendClass" then + for _, ascendClass in pairs(class.classes) do + if other.ascendancyName == ascendClass.name then + ascendClass.startNodeId = otherId + break + end + end + end + end + end + end + + return self +end + +return TreeClass diff --git a/TreeView.lua b/TreeView.lua new file mode 100644 index 00000000..100c5c14 --- /dev/null +++ b/TreeView.lua @@ -0,0 +1,568 @@ +local launch, cfg, main = ... + +local pairs = pairs +local ipairs = ipairs +local t_insert = table.insert +local m_min = math.min +local m_max = math.max +local m_floor = math.floor + +local function drawAsset(data, x, y, scale, isHalf) + local width = data.width * scale * 1.33 + local height = data.height * scale * 1.33 + if isHalf then + DrawImage(data.handle, x - width, y - height * 2, width * 2, height * 2) + DrawImage(data.handle, x - width, y, width * 2, height * 2, 0, 1, 1, 0) + else + DrawImage(data.handle, x - width, y - height, width * 2, height * 2, unpack(data)) + end +end + +local TreeViewClass = { } +TreeViewClass.__index = TreeViewClass + +function TreeViewClass:Zoom(level, viewPort) + self.zoomLevel = m_max(0, m_min(12, self.zoomLevel + level)) + local oldZoom = self.zoom + self.zoom = 1.2 ^ self.zoomLevel + local factor = self.zoom / oldZoom + local cursorX, cursorY = GetCursorPos() + local relX = cursorX - viewPort.x - viewPort.width/2 + local relY = cursorY - viewPort.y - viewPort.height/2 + self.zoomX = relX + (self.zoomX - relX) * factor + self.zoomY = relY + (self.zoomY - relY) * factor +end + +function TreeViewClass:AddNodeTooltip(node, build) + -- Special case for sockets + if node.type == "socket" and node.alloc then + local socket, jewel = build.items:GetSocketJewel(node.id) + if jewel then + build.items:AddItemTooltip(jewel, build) + else + main:AddTooltipLine(24, "^7"..node.dn..(IsKeyDown("ALT") and " ["..node.id.."]" or "")) + end + main:AddTooltipSeperator(14) + main:AddTooltipLine(14, "^x80A080Tip: Right click this socket to go to the items page and choose the jewel for this socket.") + return + end + + -- Node name + main:AddTooltipLine(24, "^7"..node.dn..(IsKeyDown("ALT") and " ["..node.id.."]" or "")) + if IsKeyDown("ALT") and node.power and node.power.dps then + main:AddTooltipLine(16, string.format("DPS power: %g Defence power: %g", node.power.dps, node.power.def)) + end + + -- Node description + if node.sd[1] then + main:AddTooltipLine(16, "") + for i, line in ipairs(node.sd) do + if node.mods[i].list then + if IsKeyDown("ALT") then + local modStr + for k, v in pairs(node.mods[i].list) do + modStr = (modStr and modStr..", " or "^2") .. string.format("%s = %s", k, tostring(v)) + end + if node.mods[i].extra then + modStr = (modStr and modStr.." " or "") .. "^1" .. node.mods[i].extra + end + if modStr then + line = line .. " " .. modStr + end + end + end + main:AddTooltipLine(16, "^7"..line) + end + end + + -- Reminder text + if node.reminderText then + main:AddTooltipSeperator(14) + for _, line in ipairs(node.reminderText) do + main:AddTooltipLine(14, "^xA0A080"..line) + end + end + + -- Mod differences + local calcFunc, calcBase = build.calcs:GetNodeCalculator(build) + if calcFunc then + main:AddTooltipSeperator(14) + local count + local nodeOutput, pathOutput + if node.alloc then + count = #node.depends + nodeOutput = calcFunc({node}, true) + pathOutput = calcFunc(node.depends, true) + else + local path = self.tracePath or node.path or { } + count = #path + nodeOutput = calcFunc({node}) + pathOutput = calcFunc(path) + end + local none = true + local header = false + for _, data in ipairs(build.displayStats) do + if data.mod then + local diff = (nodeOutput[data.mod] or 0) - (calcBase[data.mod] or 0) + if diff > 0.001 or diff < -0.001 then + none = false + if not header then + main:AddTooltipLine(14, string.format("^7%s this node will give you:", node.alloc and "Unallocating" or "Allocating")) + header = true + end + main:AddTooltipLine(14, string.format("%s%+"..data.fmt.." %s", diff > 0 and "^x00FF44" or "^xFF3300", diff * (data.pc and 100 or 1), data.label)) + end + end + end + if count > 1 then + header = false + for _, data in ipairs(build.displayStats) do + if data.mod then + local diff = (pathOutput[data.mod] or 0) - (calcBase[data.mod] or 0) + if diff > 0.001 or diff < -0.001 then + none = false + if not header then + main:AddTooltipLine(14, string.format("^7%s this node and all nodes %s will give you:", node.alloc and "Unallocating" or "Allocating", node.alloc and "depending on it" or "leading to it")) + header = true + end + main:AddTooltipLine(14, string.format("%s%+"..data.fmt.." %s", diff > 0 and "^x00FF44" or "^xFF3300", diff * (data.pc and 100 or 1), data.label)) + end + end + end + end + if none then + main:AddTooltipLine(14, string.format("^7No changes from %s this node%s.", node.alloc and "unallocating" or "allocating", count > 1 and " or the nodes leading to it" or "")) + end + end + + -- Pathing distance + if node.path and #node.path > 0 then + main:AddTooltipSeperator(14) + main:AddTooltipLine(14, "^7"..#node.path .. " points to node") + if #node.path > 1 then + main:AddTooltipLine(14, "^x80A080") + main:AddTooltipLine(14, "Tip: To reach this node by a different path, hold Shift, then trace the path and click this node") + end + end +end + +function TreeViewClass:DrawTree(build, viewPort, inputEvents) + local tree = build.tree + local spec = build.spec + + self.build = build + self.viewPort = viewPort + viewPort.height = viewPort.height - 32 + + local treeClick + common.controlsInput(self, inputEvents) + for id, event in ipairs(inputEvents) do + if event.type == "KeyDown" then + if event.key == "LEFTBUTTON" then + self.dragX, self.dragY = GetCursorPos() + elseif event.key == "z" and IsKeyDown("CTRL") then + spec:Undo() + elseif event.key == "y" and IsKeyDown("CTRL") then + spec:Redo() + elseif event.key == "h" then + self.showHeatMap = not self.showHeatMap + end + elseif event.type == "KeyUp" then + if event.key == "LEFTBUTTON" then + if self.dragX and not self.dragging then + treeClick = "LEFT" + end + elseif event.key == "RIGHTBUTTON" then + treeClick = "RIGHT" + elseif event.key == "WHEELUP" then + self:Zoom(IsKeyDown("SHIFT") and 3 or 1, viewPort) + elseif event.key == "WHEELDOWN" then + self:Zoom(IsKeyDown("SHIFT") and -3 or -1, viewPort) + end + end + end + + local cursorX, cursorY = GetCursorPos() + + if not IsKeyDown("LEFTBUTTON") then + self.dragging = false + self.dragX, self.dragY = nil, nil + end + if self.dragX then + if not self.dragging then + if math.abs(cursorX - self.dragX) > 5 or math.abs(cursorY - self.dragY) > 5 then + self.dragging = true + end + end + if self.dragging then + self.zoomX = self.zoomX + cursorX - self.dragX + self.zoomY = self.zoomY + cursorY - self.dragY + self.dragX, self.dragY = cursorX, cursorY + end + end + + local scale = m_min(viewPort.width, viewPort.height) / tree.size * self.zoom + local function treeToScreen(x, y) + return x * scale + self.zoomX + viewPort.x + viewPort.width/2, + y * scale + self.zoomY + viewPort.y + viewPort.height/2 + end + local function screenToTree(x, y) + return (x - self.zoomX - viewPort.x - viewPort.width/2) / scale, + (y - self.zoomY - viewPort.y - viewPort.height/2) / scale + end + + if IsKeyDown("SHIFT") then + self.traceMode = true + self.tracePath = self.tracePath or { } + else + self.traceMode = false + self.tracePath = nil + end + + local hoverNode + if cursorX >= viewPort.x and cursorX < viewPort.x + viewPort.width and cursorY >= viewPort.y and cursorY < viewPort.y + viewPort.height then + local curTreeX, curTreeY = screenToTree(cursorX, cursorY) + for id, node in pairs(spec.nodes) do + if node.rsq then + local vX = curTreeX - node.x + local vY = curTreeY - node.y + if vX * vX + vY * vY <= node.rsq then + if self.traceMode then + if not node.path then + break + elseif not self.tracePath[1] then + for _, pathNode in ipairs(node.path) do + t_insert(self.tracePath, 1, pathNode) + end + else + local lastPathNode = self.tracePath[#self.tracePath] + if node ~= lastPathNode then + if isValueInArray(self.tracePath, node) then + break + end + if not isValueInArray(node.linked, lastPathNode) then + break + end + t_insert(self.tracePath, node) + end + end + end + hoverNode = node + break + end + end + end + end + local hoverPath, hoverDep + if self.traceMode then + hoverPath = { } + for _, pathNode in pairs(self.tracePath) do + hoverPath[pathNode] = true + end + elseif hoverNode and hoverNode.path then + hoverPath = { } + for _, pathNode in pairs(hoverNode.path) do + hoverPath[pathNode] = true + end + hoverDep = { } + for _, depNode in pairs(hoverNode.depends) do + hoverDep[depNode] = true + end + end + + if treeClick == "LEFT" then + if hoverNode then + if hoverNode.alloc then + spec:DeallocNode(hoverNode) + spec:AddUndoState() + elseif hoverNode.path then + spec:AllocNode(hoverNode, self.tracePath and hoverNode == self.tracePath[#self.tracePath] and self.tracePath) + spec:AddUndoState() + end + end + elseif treeClick == "RIGHT" then + if hoverNode and hoverNode.alloc and hoverNode.type == "socket" then + build.viewMode = "ITEMS" + local slot = build.items.sockets[hoverNode.id] + slot.dropDown.dropped = true + build.items.selControl = slot + end + end + + local bg = tree.assets.Background1 + local bgSize = bg.width * scale * 1.33 * 2.5 + SetDrawColor(1, 1, 1) + DrawImage(bg.handle, viewPort.x, viewPort.y, viewPort.width, viewPort.height, (self.zoomX + viewPort.width/2) / -bgSize, (self.zoomY + viewPort.height/2) / -bgSize, (viewPort.width/2 - self.zoomX) / bgSize, (viewPort.height/2 - self.zoomY) / bgSize) + + local curAscendName = tree.classes[spec.curClassId].classes[tostring(spec.curAscendClassId)].name + + for _, group in pairs(tree.groups) do + local scrX, scrY = treeToScreen(group.x, group.y) + if group.ascendancyName then + if group.isAscendancyStart then + if group.ascendancyName ~= curAscendName then + SetDrawColor(1, 1, 1, 0.25) + end + drawAsset(tree.assets["Classes"..group.ascendancyName], scrX, scrY, scale) + SetDrawColor(1, 1, 1) + end + elseif group.oo["3"] then + drawAsset(tree.assets.PSGroupBackground3, scrX, scrY, scale, true) + elseif group.oo["2"] then + drawAsset(tree.assets.PSGroupBackground2, scrX, scrY, scale) + elseif group.oo["1"] then + drawAsset(tree.assets.PSGroupBackground1, scrX, scrY, scale) + end + end + + for _, conn in pairs(tree.conn) do + local state = "Normal" + local node1, node2 = spec.nodes[conn.nodeId1], spec.nodes[conn.nodeId2] + if node1.alloc and node2.alloc then + state = "Active" + elseif hoverPath then + if (node1.alloc or node1 == hoverNode or hoverPath[node1]) and (node2.alloc or node2 == hoverNode or hoverPath[node2]) then + state = "Intermediate" + end + end + local vert = conn.vert[state] + conn.c[1], conn.c[2] = treeToScreen(vert[1], vert[2]) + conn.c[3], conn.c[4] = treeToScreen(vert[3], vert[4]) + conn.c[5], conn.c[6] = treeToScreen(vert[5], vert[6]) + conn.c[7], conn.c[8] = treeToScreen(vert[7], vert[8]) + if hoverDep and hoverDep[node1] and hoverDep[node2] then + SetDrawColor(1, 0, 0) + elseif conn.ascendancyName and conn.ascendancyName ~= curAscendName then + SetDrawColor(0.75, 0.75, 0.75) + end + DrawImageQuad(tree.assets[conn.type..state].handle, unpack(conn.c)) + SetDrawColor(1, 1, 1) + end + + for id, node in pairs(spec.nodes) do + local base, overlay + if node.type == "class" then + overlay = node.alloc and node.startArt or "PSStartNodeBackgroundInactive" + elseif node.type == "ascendClass" then + overlay = "PassiveSkillScreenAscendancyMiddle" + elseif node.type == "mastery" then + base = node.sprites.mastery + else + local state + if self.showHeatMap or node.alloc or node == hoverNode or (self.traceMode and node == self.tracePath[#self.tracePath])then + state = "alloc" + elseif hoverPath and hoverPath[node] then + state = "path" + else + state = "unalloc" + end + if node.type == "socket" then + base = tree.assets[node.overlay[state .. (node.ascendancyName and "Ascend" or "")]] + local jewel = node.alloc and build.items.list[build.items.sockets[id].selItem] + if jewel then + if jewel.baseName == "Crimson Jewel" then + overlay = "JewelSocketActiveRed" + elseif jewel.baseName == "Viridian Jewel" then + overlay = "JewelSocketActiveGreen" + elseif jewel.baseName == "Cobalt Jewel" then + overlay = "JewelSocketActiveBlue" + end + end + else + base = node.sprites[node.type..(node.alloc and "Active" or "Inactive")] + overlay = node.overlay[state .. (node.ascendancyName and "Ascend" or "")] + end + end + local scrX, scrY = treeToScreen(node.x, node.y) + if node.ascendancyName and node.ascendancyName ~= curAscendName then + SetDrawColor(0.5, 0.5, 0.5) + end + if IsKeyDown("ALT") then + if node.extra then + SetDrawColor(1, 0, 0) + elseif node.unknown then + SetDrawColor(0, 1, 1) + else + SetDrawColor(0, 0, 0) + end + end + if self.showHeatMap then + if build.calcs.powerBuildFlag then + build.calcs:BuildPower() + end + if not node.alloc and node.type ~= "class" and node.type ~= "ascendClass" then + local dps = m_max(node.power.dps or 0, 0) + local def = m_max(node.power.def or 0, 0) + local dpsCol = (dps / build.calcs.powerMax.dps * 1.5) ^ 0.5 + local defCol = (def / build.calcs.powerMax.def * 1.5) ^ 0.5 + SetDrawColor(dpsCol, (dpsCol + defCol) / 4, defCol) + else + SetDrawColor(1, 1, 1) + end + end + if base then + drawAsset(base, scrX, scrY, scale) + end + if overlay then + if node.type ~= "class" and node.type ~= "ascendClass" then + if #self.searchStr > 0 then + local errMsg, match = PCall(string.match, node.dn:lower(), self.searchStr:lower()) + if not match then + for index, line in ipairs(node.sd) do + errMsg, match = PCall(string.match, line:lower(), self.searchStr:lower()) + if not match and node.mods[index].list then + for k in pairs(node.mods[index].list) do + errMsg, match = PCall(string.match, k, self.searchStr) + if match then + break + end + end + end + if match then + break + end + end + end + if match then + local col = math.sin((GetTime() / 100) % 360) / 2 + 0.5 + SetDrawColor(col, col, col) + end + end + if hoverNode and hoverNode ~= node then + if hoverDep and hoverDep[node] then + SetDrawColor(1, 0, 0) + end + if hoverNode.type == "socket" then + local vX, vY = node.x - hoverNode.x, node.y - hoverNode.y + local dSq = vX * vX + vY * vY + for _, data in ipairs(data.jewelRadius) do + if dSq <= data.rad * data.rad then + SetDrawColor(data.col) + break + end + end + end + end + end + drawAsset(tree.assets[overlay], scrX, scrY, scale) + SetDrawColor(1, 1, 1) + end + end + + for nodeId, slot in pairs(build.items.sockets) do + local node = spec.nodes[nodeId] + if node == hoverNode then + local scrX, scrY = treeToScreen(node.x, node.y) + for _, radData in ipairs(data.jewelRadius) do + local size = radData.rad * scale + SetDrawColor(radData.col) + DrawImage(self.ring, scrX - size, scrY - size, size * 2, size * 2) + end + elseif node.alloc then + local socket, jewel = build.items:GetSocketJewel(nodeId) + if jewel and jewel.radius then + local scrX, scrY = treeToScreen(node.x, node.y) + local radData = data.jewelRadius[jewel.radius] + local size = radData.rad * scale + SetDrawColor(radData.col) + DrawImage(self.ring, scrX - size, scrY - size, size * 2, size * 2) + end + end + end + + if hoverNode then + self:AddNodeTooltip(hoverNode, build) + local scrX, scrY = treeToScreen(hoverNode.x, hoverNode.y) + local size = m_floor(hoverNode.size * scale) + main:DrawTooltip(m_floor(scrX - size), m_floor(scrY - size), size * 2, size * 2, viewPort) + end + + SetDrawColor(0.05, 0.05, 0.05) + DrawImage(nil, viewPort.x, viewPort.y + viewPort.height + 4, viewPort.width, 28) + SetDrawColor(0.85, 0.85, 0.85) + DrawImage(nil, viewPort.x, viewPort.y + viewPort.height, viewPort.width, 4) + common.controlsDraw(self, viewPort) +end + +function TreeViewClass:Load(xml, fileName) + if xml.attrib.zoomLevel then + self.zoomLevel = tonumber(xml.attrib.zoomLevel) + self.zoom = 1.2 ^ self.zoomLevel + end + if xml.attrib.zoomX and xml.attrib.zoomY then + self.zoomX = tonumber(xml.attrib.zoomX) + self.zoomY = tonumber(xml.attrib.zoomY) + end + if xml.attrib.searchStr then + self.searchStr = xml.attrib.searchStr + self.controls.treeSearch:SetText(self.searchStr) + end + if xml.attrib.showHeatMap then + self.showHeatMap = xml.attrib.showHeatMap == "true" + end +end +function TreeViewClass:Save(xml) + xml.attrib = { + zoomLevel = tostring(self.zoomLevel), + zoomX = tostring(self.zoomX), + zoomY = tostring(self.zoomY), + searchStr = self.searchStr, + showHeatMap = tostring(self.showHeatMap), + } +end + +function TreeViewClass.NewTreeView() + local self = setmetatable({}, TreeViewClass) + + self.ring = NewImageHandle() + self.ring:Load("ring.png") + + self.zoomLevel = 3 + self.zoom = 1.2 ^ self.zoomLevel + self.zoomX = 0 + self.zoomY = 0 + + self.searchStr = "" + + self.controls = { } + t_insert(self.controls, common.newButton(function() return self.viewPort.x + 4 end, function() return self.viewPort.y + self.viewPort.height + 8 end, 60, 20, "Reset", function() + launch:ShowPrompt(1, 0, 0, "Are you sure to want to reset your tree?\nPress Y to continue.", function(key) + if key == "y" then + self.build.spec:ResetNodes() + self.build.spec:AddUndoState() + end + return true + end) + end)) + t_insert(self.controls, common.newButton(function() return self.viewPort.x + 4 + 68*1 end, function() return self.viewPort.y + self.viewPort.height + 8 end, 60, 20, "Import", function() + launch:ShowPrompt(0, 0, 0, "Press Ctrl+V to import passive tree link.", function(key) + if key == "v" and IsKeyDown("CTRL") then + local url = Paste() + if url and #url > 0 then + self.build.spec:DecodeURL(url) + self.build.spec:AddUndoState() + end + return true + elseif key == "ESCAPE" then + return true + end + end) + end)) + t_insert(self.controls, common.newButton(function() return self.viewPort.x + 4 + 68*2 end, function() return self.viewPort.y + self.viewPort.height + 8 end, 60, 20, "Export", function() + launch:ShowPrompt(0, 0, 0, "Press Ctrl+C to copy passive tree link.", function(key) + if key == "c" and IsKeyDown("CTRL") then + Copy(self.build.spec:EncodeURL("https://www.pathofexile.com/passive-skill-tree/")) + return true + elseif key == "ESCAPE" then + return true + end + end) + end)) + self.controls.treeSearch = common.newEditControl(function() return self.viewPort.x + 4 + 68*3 end, function() return self.viewPort.y + self.viewPort.height + 8 end, 400, 20, "", "Search", "[^%c%(%)]", 100, nil, function(buf) + self.searchStr = buf + end) + + return self +end + +return TreeViewClass \ No newline at end of file diff --git a/ring.png b/ring.png new file mode 100644 index 00000000..dad14b18 Binary files /dev/null and b/ring.png differ