Release 1.4.19

- Added folder support to build list
This commit is contained in:
Openarl
2017-06-07 18:08:31 +10:00
parent a0a87576b8
commit cf81e7531a
15 changed files with 768 additions and 215 deletions

View File

@@ -5,12 +5,37 @@
--
local launch, main = ...
local ipairs = ipairs
local s_format = string.format
local BuildListClass = common.NewClass("BuildList", "ListControl", function(self, anchor, x, y, width, height, listMode)
self.ListControl(anchor, x, y, width, height, 20, false, listMode.list)
self.listMode = listMode
self.showRowSeparators = true
self.controls.path = common.New("PathControl", {"BOTTOM",self,"TOP"}, 0, -2, width, 24, main.buildPath, listMode.subPath, function(subPath)
listMode.subPath = subPath
listMode:BuildList()
self.selIndex = nil
self.selValue = nil
end)
function self.controls.path:CanReceiveDrag(type, build)
return type == "Build" and #self.folderList > 1
end
function self.controls.path:ReceiveDrag(type, build, source)
if type == "Build" then
for index, folder in ipairs(self.folderList) do
if index < #self.folderList and folder.button:IsMouseOver() then
if build.folderName then
main:MoveFolder(build.folderName, main.buildPath..build.subPath, main.buildPath..folder.path)
else
os.rename(build.fullFileName, listMode:GetDestName(folder.path, build.fileName))
end
listMode:BuildList()
end
end
end
end
self.dragTargetList = { self.controls.path, self }
end)
function BuildListClass:SelByFileName(selFileName)
@@ -23,52 +48,74 @@ function BuildListClass:SelByFileName(selFileName)
end
function BuildListClass:LoadBuild(build)
main:SetMode("BUILD", main.buildPath..build.fileName, build.buildName)
if build.folderName then
self.controls.path:SetSubPath(self.listMode.subPath .. build.folderName .. "/")
else
main:SetMode("BUILD", build.fullFileName, build.buildName)
end
end
function BuildListClass:NewFolder()
main:OpenNewFolderPopup(main.buildPath..self.listMode.subPath, function(newFolderName)
if newFolderName then
self.listMode:BuildList()
end
self.listMode:SelectControl(self)
end)
end
function BuildListClass:RenameBuild(build, copyOnName)
local controls = { }
controls.label = common.New("LabelControl", nil, 0, 20, 0, 16, "^7Enter the new name for this build:")
controls.edit = common.New("EditControl", nil, 0, 40, 350, 20, build.buildName, nil, "\\/:%*%?\"<>|%c", 100, function(buf)
controls.label = common.New("LabelControl", nil, 0, 20, 0, 16, "^7Enter the new name for this "..(build.folderName and "folder:" or "build:"))
controls.edit = common.New("EditControl", nil, 0, 40, 350, 20, build.folderName or build.buildName, nil, "\\/:%*%?\"<>|%c", 100, function(buf)
controls.save.enabled = false
if buf:match("%S") and buf:lower() ~= build.buildName:lower() then
local newName = buf..".xml"
local newFile = io.open(main.buildPath..newName, "r")
if newFile then
newFile:close()
else
if build.folderName then
if buf:match("%S") and buf:lower() ~= build.folderName:lower() then
controls.save.enabled = true
end
else
if buf:match("%S") and buf:lower() ~= build.buildName:lower() then
local newName = buf..".xml"
local newFile = io.open(main.buildPath..build.subPath..newName, "r")
if newFile then
newFile:close()
else
controls.save.enabled = true
end
end
end
end)
controls.save = common.New("ButtonControl", nil, -45, 70, 80, 20, "Save", function()
local newBuildName = controls.edit.buf
local newFileName = newBuildName..".xml"
if copyOnName then
local inFile, msg = io.open(main.buildPath..build.fileName, "r")
if not inFile then
main:OpenMessagePopup("Error", "Couldn't open '"..build.fileName.."': "..msg)
return
if build.folderName then
if copyOnName then
main:CopyFolder(build.fullFileName, main.buildPath..build.subPath..newBuildName)
else
local res, msg = os.rename(build.fullFileName, main.buildPath..build.subPath..newBuildName)
if not res then
main:OpenMessagePopup("Error", "Couldn't rename '"..build.fullFileName.."' to '"..newBuildName.."': "..msg)
return
end
end
local outFile, msg = io.open(main.buildPath..newFileName, "w")
if not outFile then
main:OpenMessagePopup("Error", "Couldn't create '"..newFileName.."': "..msg)
return
end
outFile:write(inFile:read("*a"))
inFile:close()
outFile:close()
self.listMode:BuildList()
else
local res, msg = os.rename(main.buildPath..build.fileName, main.buildPath..newFileName)
if not res then
main:OpenMessagePopup("Error", "Couldn't rename '"..build.fileName.."' to '"..newFileName.."': "..msg)
return
local newFileName = newBuildName..".xml"
if copyOnName then
local res, msg = copyFile(build.fullFileName, main.buildPath..build.subPath..newFileName)
if not res then
main:OpenMessagePopup("Error", "Couldn't copy build: "..msg)
return
end
else
local res, msg = os.rename(build.fullFileName, main.buildPath..build.subPath..newFileName)
if not res then
main:OpenMessagePopup("Error", "Couldn't rename '"..build.fullFileName.."' to '"..newFileName.."': "..msg)
return
end
end
build.buildName = newBuildName
build.fileName = newFileName
self.listMode:BuildList()
self:SelByFileName(newFileName)
end
self.listMode:BuildList()
self:SelByFileName(newFileName)
main:ClosePopup()
self.listMode:SelectControl(self)
end)
@@ -77,44 +124,109 @@ function BuildListClass:RenameBuild(build, copyOnName)
main:ClosePopup()
self.listMode:SelectControl(self)
end)
main:OpenPopup(370, 100, copyOnName and "Copy Build" or "Rename Build", controls, "save", "edit")
main:OpenPopup(370, 100, (copyOnName and "Copy " or "Rename ")..(build.folderName and "Folder" or "Build"), controls, "save", "edit")
end
function BuildListClass:DeleteBuild(build)
main:OpenConfirmPopup("Confirm Delete", "Are you sure you want to delete build:\n"..build.buildName.."\nThis cannot be undone.", "Delete", function()
os.remove(main.buildPath..build.fileName)
self.listMode:BuildList()
self.selIndex = nil
self.selValue = nil
end)
if build.folderName then
if NewFileSearch(build.fullFileName.."/*") or NewFileSearch(build.fullFileName.."/*", true) then
main:OpenMessagePopup("Delete Folder", "The folder is not empty.")
else
local res, msg = RemoveDir(build.fullFileName)
if not res then
main:OpenMessagePopup("Error", "Couldn't delete '"..build.fullFileName.."': "..msg)
return
end
self.listMode:BuildList()
self.selIndex = nil
self.selValue = nil
end
else
main:OpenConfirmPopup("Confirm Delete", "Are you sure you want to delete build:\n"..build.buildName.."\nThis cannot be undone.", "Delete", function()
os.remove(build.fullFileName)
self.listMode:BuildList()
self.selIndex = nil
self.selValue = nil
end)
end
end
function BuildListClass:GetColumnOffset(column)
if column == 1 then
return 0
elseif column == 2 then
return self:GetProperty("width") - 164
return self:GetProperty("width") - 172
end
end
function BuildListClass:GetRowValue(column, index, build)
if column == 1 then
return build.buildName or "?"
local label
if build.folderName then
label = ">> " .. build.folderName
else
label = build.buildName or "?"
end
if self.cutBuild and self.cutBuild.buildName == build.buildName and self.cutBuild.folderName == build.folderName then
return "^xC0B0B0"..label
else
return label
end
elseif column == 2 then
return s_format("%sLevel %d %s",
build.className and data.colorCodes[build.className:upper()] or "^7",
build.level or 1,
(build.ascendClassName ~= "None" and build.ascendClassName) or build.className or "?"
)
if build.buildName then
return s_format("%sLevel %d %s",
build.className and data.colorCodes[build.className:upper()] or "^7",
build.level or 1,
(build.ascendClassName ~= "None" and build.ascendClassName) or build.className or "?"
)
else
return ""
end
end
end
function BuildListClass:GetDragValue(index, build)
return "Build", build
end
function BuildListClass:CanReceiveDrag(type, build)
return type == "Build"
end
function BuildListClass:ReceiveDrag(type, build, source)
if type == "Build" then
if self.hoverValue and self.hoverValue.folderName then
if build.folderName then
main:MoveFolder(build.folderName, main.buildPath..build.subPath, main.buildPath..self.hoverValue.subPath..self.hoverValue.folderName.."/")
else
os.rename(build.fullFileName, self.listMode:GetDestName(self.listMode.subPath..self.hoverValue.folderName.."/", build.fileName))
end
self.listMode:BuildList()
end
end
end
function BuildListClass:CanDragToValue(index, build, source)
return build.folderName
end
function BuildListClass:OnSelClick(index, build, doubleClick)
if doubleClick then
self:LoadBuild(build)
self.selDragging = false
end
end
function BuildListClass:OnSelCopy(index, build)
self.copyBuild = build
self.cutBuild = nil
end
function BuildListClass:OnSelCut(index, build)
self.copyBuild = nil
self.cutBuild = build
end
function BuildListClass:OnSelDelete(index, build)
self:DeleteBuild(build)
end

View File

@@ -0,0 +1,70 @@
-- Path of Building
--
-- Class: Folder List
-- Folder list control.
--
local launch, main = ...
local ipairs = ipairs
local t_insert = table.insert
local FolderListClass = common.NewClass("FolderList", "ListControl", function(self, anchor, x, y, width, height, subPath, onChange)
self.ListControl(anchor, x, y, width, height, 16, false, { })
self.subPath = subPath or ""
self.controls.path = common.New("PathControl", {"BOTTOM",self,"TOP"}, 0, -2, width, 24, main.buildPath, self.subPath, function(subPath)
self.subPath = subPath
self:BuildList()
self.selIndex = nil
self.selValue = nil
if onChange then
onChange(subPath)
end
end)
self:BuildList()
end)
function FolderListClass:BuildList()
wipeTable(self.list)
local handle = NewFileSearch(main.buildPath..self.subPath.."*", true)
while handle do
local fileName = handle:GetFileName()
t_insert(self.list, {
name = fileName,
fullFileName = main.buildPath..self.subPath..fileName,
})
if not handle:NextFile() then
break
end
end
end
function FolderListClass:OpenFolder(folderName)
self.controls.path:SetSubPath(self.subPath .. folderName .. "/")
end
function FolderListClass:GetRowValue(column, index, folder)
if column == 1 then
return folder.name
end
end
function FolderListClass:OnSelClick(index, folder, doubleClick)
if doubleClick then
self:OpenFolder(folder.name)
end
end
function FolderListClass:OnSelDelete(index, folder)
if NewFileSearch(folder.fullFileName.."/*") or NewFileSearch(folder.fullFileName.."/*", true) then
main:OpenMessagePopup("Delete Folder", "The folder is not empty.")
else
local res, msg = RemoveDir(folder.fullFileName)
if not res then
main:OpenMessagePopup("Error", "Couldn't delete '"..folder.fullFileName.."': "..msg)
return
end
self:BuildList()
self.selIndex = nil
self.selValue = nil
end
end

View File

@@ -199,60 +199,27 @@ You can get this from your web browser's cookies while logged into the Path of E
return (self.importCodeState == "VALID" and data.colorCodes.POSITIVE.."Code is valid") or (self.importCodeState == "INVALID" and data.colorCodes.NEGATIVE.."Invalid code") or ""
end
self.controls.importCodePastebin = common.New("ButtonControl", {"LEFT",self.controls.importCodeIn,"RIGHT"}, 90, 0, 160, 20, "Import from Pastebin...", function()
local controls = { }
controls.editLabel = common.New("LabelControl", nil, 0, 20, 0, 16, "Enter Pastebin.com link:")
controls.edit = common.New("EditControl", nil, 0, 40, 250, 18, "", nil, nil, nil, function(buf)
controls.msg.label = ""
end)
controls.msg = common.New("LabelControl", nil, 0, 58, 0, 16, "")
controls.import = common.New("ButtonControl", nil, -45, 80, 80, 20, "Import", function()
controls.import.enabled = false
controls.msg.label = "Retrieving paste..."
launch:DownloadPage(controls.edit.buf:gsub("pastebin%.com/(%w+)$","pastebin.com/raw/%1"), function(page, errMsg)
if errMsg then
controls.msg.label = "^1"..errMsg
controls.import.enabled = true
else
self.controls.importCodeIn:SetText(page, true)
main:ClosePopup()
end
end)
end)
controls.import.enabled = function()
return #controls.edit.buf > 0 and controls.edit.buf:match("pastebin%.com/%w+")
end
controls.cancel = common.New("ButtonControl", nil, 45, 80, 80, 20, "Cancel", function()
main:ClosePopup()
end)
main:OpenPopup(280, 110, "Import from Pastebin", controls, "import", "edit")
self:OpenPastebinImportPopup()
end)
self.controls.importCodeMode = common.New("DropDownControl", {"TOPLEFT",self.controls.importCodeIn,"BOTTOMLEFT"}, 0, 4, 160, 20, { "Import to this build", "Import to a new build:" })
self.controls.importCodeMode = common.New("DropDownControl", {"TOPLEFT",self.controls.importCodeIn,"BOTTOMLEFT"}, 0, 4, 160, 20, { "Import to this build", "Import to a new build" })
self.controls.importCodeMode.enabled = function()
return self.importCodeState == "VALID" and self.build.dbFileName
end
self.controls.importCodeBuildName = common.New("EditControl", {"LEFT",self.controls.importCodeMode,"RIGHT"}, 4, 0, 400, 20, "", "New build name", "\\/:%*%?\"<>|%c", 100)
self.controls.importCodeBuildName.enabled = function()
return self.importCodeState == "VALID" and self.controls.importCodeMode.selIndex == 2
end
self.controls.importCodeGo = common.New("ButtonControl", {"TOPLEFT",self.controls.importCodeMode,"BOTTOMLEFT"}, 0, 8, 60, 20, "Import", function()
if self.controls.importCodeMode.selIndex == 1 then
main:OpenConfirmPopup("Build Import", "^xFF9922Warning:^7 Importing to the current build will erase ALL existing data for this build.\nThis cannot be undone.", "Import", function()
self:ImportToBuild(self.build.dbFileName, self.build.buildName)
main:OpenConfirmPopup("Build Import", "^xFF9922Warning:^7 Importing to the current build will erase ALL existing data for this build.", "Import", function()
self.build:Shutdown()
self.build:Init(self.build.dbFileName, self.build.buildName, self.importCodeXML)
self.build.viewMode = "TREE"
end)
else
local newBuildName = self.controls.importCodeBuildName.buf
local newFileName = main.buildPath .. newBuildName .. ".xml"
local file = io.open(newFileName, "r")
if file then
file:close()
main:OpenMessagePopup("Build Import", "A build with that name already exists.")
return
end
self:ImportToBuild(newFileName, newBuildName)
self.build:Shutdown()
self.build:Init(false, "Imported build", self.importCodeXML)
self.build.viewMode = "TREE"
end
end)
self.controls.importCodeGo.enabled = function()
return self.importCodeState == "VALID" and (self.controls.importCodeMode.selIndex == 1 or self.controls.importCodeBuildName.buf:match("%S"))
return self.importCodeState == "VALID"
end
end)
@@ -709,6 +676,35 @@ function ImportTabClass:ImportSocketedSkills(item, socketedItems, slotName)
end
end
function ImportTabClass:OpenPastebinImportPopup()
local controls = { }
controls.editLabel = common.New("LabelControl", nil, 0, 20, 0, 16, "Enter Pastebin.com link:")
controls.edit = common.New("EditControl", nil, 0, 40, 250, 18, "", nil, nil, nil, function(buf)
controls.msg.label = ""
end)
controls.msg = common.New("LabelControl", nil, 0, 58, 0, 16, "")
controls.import = common.New("ButtonControl", nil, -45, 80, 80, 20, "Import", function()
controls.import.enabled = false
controls.msg.label = "Retrieving paste..."
launch:DownloadPage(controls.edit.buf:gsub("pastebin%.com/(%w+)$","pastebin.com/raw/%1"), function(page, errMsg)
if errMsg then
controls.msg.label = "^1"..errMsg
controls.import.enabled = true
else
self.controls.importCodeIn:SetText(page, true)
main:ClosePopup()
end
end)
end)
controls.import.enabled = function()
return #controls.edit.buf > 0 and controls.edit.buf:match("pastebin%.com/%w+")
end
controls.cancel = common.New("ButtonControl", nil, 45, 80, 80, 20, "Cancel", function()
main:ClosePopup()
end)
main:OpenPopup(280, 110, "Import from Pastebin", controls, "import", "edit")
end
function ImportTabClass:ProcessJSON(json)
local func, errMsg = loadstring("return "..jsonToLua(json))
if errMsg then
@@ -721,16 +717,3 @@ function ImportTabClass:ProcessJSON(json)
end
return data
end
function ImportTabClass:ImportToBuild(buildFileName, buildName)
self.build:Shutdown()
local file = io.open(buildFileName, "w+")
if not file then
main:ShowMessagePopup("Build Import", "^xFF2222Error:^7 Couldn't create build file (invalid name?)")
return
end
file:write(self.importCodeXML)
file:close()
self.build:Init(buildFileName, buildName)
self.build.viewMode = "TREE"
end

View File

@@ -112,7 +112,7 @@ function ListClass:Draw(viewPort)
if label then
DrawString(x, y - 20, "LEFT", 16, "VAR", label)
end
if self.otherDragSource then
if self.otherDragSource and not self.CanDragToValue then
SetDrawColor(0.2, 0.6, 0.2)
elseif self.hasFocus then
SetDrawColor(1, 1, 1)
@@ -120,7 +120,7 @@ function ListClass:Draw(viewPort)
SetDrawColor(0.5, 0.5, 0.5)
end
DrawImage(nil, x, y, width, height)
if self.otherDragSource then
if self.otherDragSource and not self.CanDragToValue then
SetDrawColor(0, 0.05, 0)
else
SetDrawColor(0, 0, 0)
@@ -151,7 +151,7 @@ function ListClass:Draw(viewPort)
text = text:sub(1, clipIndex - 1) .. "..."
textWidth = DrawStringWidth(textHeight, "VAR", text)
end
if not scrollBar.dragging and not self.selDragActive then
if not scrollBar.dragging and (not self.selDragActive or (self.CanDragToValue and self:CanDragToValue(index, value, self.otherDragSource))) then
local cursorX, cursorY = GetCursorPos()
local relX = cursorX - (x + 2)
local relY = cursorY - (y + 2)
@@ -174,6 +174,8 @@ function ListClass:Draw(viewPort)
DrawImage(nil, colOffset, lineY, colWidth, rowHeight)
if (value == self.selValue or value == ttValue) then
SetDrawColor(0.33, 0.33, 0.33)
elseif self.otherDragSource and self.CanDragToValue and self:CanDragToValue(index, value, self.otherDragSource) then
SetDrawColor(0, 0.2, 0)
elseif index % 2 == 0 then
SetDrawColor(0.05, 0.05, 0.05)
else
@@ -189,7 +191,11 @@ function ListClass:Draw(viewPort)
SetDrawColor(0.5, 0.5, 0.5)
end
DrawImage(nil, colOffset, lineY, colWidth, rowHeight)
SetDrawColor(0.15, 0.15, 0.15)
if self.otherDragSource and self.CanDragToValue and self:CanDragToValue(index, value, self.otherDragSource) then
SetDrawColor(0, 0.2, 0)
else
SetDrawColor(0.15, 0.15, 0.15)
end
DrawImage(nil, colOffset, lineY + 1, colWidth, rowHeight - 2)
end
SetDrawColor(1, 1, 1)
@@ -219,6 +225,8 @@ function ListClass:Draw(viewPort)
DrawString(cursorX + 1, cursorY - 7, "LEFT", 16, "VAR", text)
SetDrawLayer(nil, 0)
end
self.hoverIndex = ttIndex
self.hoverValue = ttValue
if ttIndex and self.AddValueTooltip then
local col, center = self:AddValueTooltip(ttIndex, ttValue)
SetDrawLayer(nil, 100)
@@ -249,21 +257,21 @@ function ListClass:OnKeyDown(key, doubleClick)
self.selValue = self.list[index]
if self.selValue then
self.selIndex = index
if self.OnSelect then
self:OnSelect(self.selIndex, self.selValue)
end
if self.OnSelClick then
self:OnSelClick(self.selIndex, self.selValue, doubleClick)
end
if (self.isMutable or self.dragTargetList) and self:IsShown() then
self.selCX = cursorX
self.selCY = cursorY
self.selDragging = true
self.selDragActive = false
end
if self.OnSelect then
self:OnSelect(self.selIndex, self.selValue)
end
if self.OnSelClick then
self:OnSelClick(self.selIndex, self.selValue, doubleClick)
end
end
end
elseif #self.list > 0 then
elseif #self.list > 0 and not self.selDragActive then
if key == "UP" then
self:SelectIndex(((self.selIndex or 1) - 2) % #self.list + 1)
elseif key == "DOWN" then
@@ -277,6 +285,10 @@ function ListClass:OnKeyDown(key, doubleClick)
if self.OnSelCopy then
self:OnSelCopy(self.selIndex, self.selValue)
end
elseif key == "x" and IsKeyDown("CTRL") then
if self.OnSelCut then
self:OnSelCut(self.selIndex, self.selValue)
end
elseif key == "BACK" or key == "DELETE" then
if self.OnSelDelete then
self:OnSelDelete(self.selIndex, self.selValue)

108
Classes/PathControl.lua Normal file
View File

@@ -0,0 +1,108 @@
-- Path of Building
--
-- Class: Path Control
-- Path control.
--
local launch, main = ...
local ipairs = ipairs
local t_insert = table.insert
local PathClass = common.NewClass("PathControl", "Control", "ControlHost", "UndoHandler", function(self, anchor, x, y, width, height, basePath, subPath, onChange)
self.Control(anchor, x, y, width, height)
self.ControlHost()
self.UndoHandler()
self.basePath = basePath
self.baseName = basePath:match("([^/]+)/$") or "Base"
self:SetSubPath(subPath or "")
self:ResetUndo()
self.onChange = onChange
end)
function PathClass:SetSubPath(subPath, noUndo)
if subPath == self.subPath then
return
end
self.subPath = subPath
self.folderList = {
{ label = self.baseName, path = "" },
}
for folder, endIndex in subPath:gmatch("([^/]+)()") do
t_insert(self.folderList, { label = folder, path = subPath:sub(1, endIndex) })
end
local x = 2
local i = 1
for index, folder in ipairs(self.folderList) do
local button = self.controls["folder"..i]
if not button then
button = common.New("ButtonControl", {"LEFT",self,"LEFT"}, 0, 0, 0, self.height - 4)
self.controls["folder"..i] = button
end
button.shown = true
button.x = x
button.label = folder.label
button.width = DrawStringWidth(self.height - 8, "VAR", folder.label) + 10
button.onClick = function()
self:SetSubPath(folder.path)
end
folder.button = button
x = x + button.width + 12
i = i + 1
end
while self.controls["folder"..i] do
self.controls["folder"..i].shown = false
i = i + 1
end
if self.onChange then
self.onChange(subPath)
end
if not noUndo then
self:AddUndoState()
end
end
function PathClass:IsMouseOver()
if not self:IsShown() then
return
end
return self:IsMouseInBounds() or self:GetMouseOverControl()
end
function PathClass:Draw(viewPort)
local x, y = self:GetPos()
local width, height = self:GetSize()
SetDrawColor(0.5, 0.5, 0.5)
DrawImage(nil, x, y, width, height)
SetDrawColor(0, 0, 0)
DrawImage(nil, x + 1, y + 1, width - 2, height - 2)
self:DrawControls(viewPort)
for index, folder in ipairs(self.folderList) do
local buttonX, buttonY = folder.button:GetPos()
local buttonW, buttonH = folder.button:GetSize()
SetDrawColor(1, 1, 1)
main:DrawArrow(buttonX + buttonW + 6, y + height/2, 8, "RIGHT")
if self.otherDragSource and index < #self.folderList then
SetDrawColor(0, 1, 0, 0.25)
DrawImage(nil, buttonX, buttonY, buttonW, buttonH)
end
end
end
function PathClass:OnKeyDown(key, doubleClick)
if not self:IsShown() or not self:IsEnabled() then
return
end
local mOverControl = self:GetMouseOverControl()
if mOverControl and mOverControl.OnKeyDown then
return mOverControl:OnKeyDown(key)
end
end
function PathClass:CreateUndoState()
return self.subPath
end
function PathClass:RestoreUndoState(state)
self:SetSubPath(state, true)
end

View File

@@ -426,6 +426,7 @@ Variant: Pre 1.1.0
Variant: Pre 2.0.0
Variant: Current
Requires Level 68, 85 Str, 85 Int
Implicits: 2
{variant:1}+24% to all Elemental Resistances
{variant:2,3}+12% to all Elemental Resistances
{variant:1,2}+1 to Level of Aura Gems in this item

View File

@@ -35,7 +35,7 @@ local mercilessBanditDropList = {
local buildMode = common.New("ControlHost")
function buildMode:Init(dbFileName, buildName)
function buildMode:Init(dbFileName, buildName, buildXML)
self.abortSave = true
self.tree = main.tree
@@ -53,7 +53,7 @@ function buildMode:Init(dbFileName, buildName)
if self.unsaved then
self:OpenSavePopup("LIST")
else
main:SetMode("LIST", self.dbFileName and self.buildName)
self:CloseBuild()
end
end)
self.controls.buildName = common.New("Control", {"LEFT",self.controls.back,"RIGHT"}, 8, 0, 0, 20)
@@ -75,9 +75,13 @@ function buildMode:Init(dbFileName, buildName)
SetViewport(x, y + 2, self.strWidth + 94, 16)
DrawString(0, 0, "LEFT", 16, "VAR", "Current build: "..self.buildName)
SetViewport()
if control:IsMouseInBounds() and self.strLimited then
if control:IsMouseInBounds() then
SetDrawLayer(nil, 10)
main:AddTooltipLine(16, self.buildName)
if self.dbFileSubPath and self.dbFileSubPath ~= "" then
main:AddTooltipLine(16, self.dbFileSubPath..self.buildName)
elseif self.strLimited then
main:AddTooltipLine(16, self.buildName)
end
main:DrawTooltip(x, y, width, height, main.viewPort)
SetDrawLayer(nil, 0)
end
@@ -377,6 +381,11 @@ function buildMode:Init(dbFileName, buildName)
self.dbFileName = dbFileName
self.buildName = buildName
if dbFileName then
self.dbFileSubPath = self.dbFileName:sub(#main.buildPath + 1, -#self.buildName - 5)
else
self.dbFileSubPath = main.modes.LIST.subPath or ""
end
self.characterLevel = 1
self.controls.characterLevel:SetText(tostring(self.characterLevel))
@@ -401,9 +410,18 @@ function buildMode:Init(dbFileName, buildName)
["Spec"] = self.treeTab,
}
if self:LoadDBFile() then
main:SetMode("LIST", buildName)
return
if buildXML then
if self:LoadDB(buildXML, "Imported build") then
self:CloseBuild()
return
end
self.modFlag = true
else
if self:LoadDBFile() then
self:CloseBuild()
return
end
self.modFlag = false
end
if next(self.configTab.input) == nil then
@@ -457,6 +475,14 @@ function buildMode:Shutdown()
self.savers = nil
end
function buildMode:GetArgs()
return self.dbFileName, self.buildName
end
function buildMode:CloseBuild()
main:SetMode("LIST", self.dbFileName and self.buildName, self.dbFileSubPath)
end
function buildMode:Load(xml, fileName)
if xml.attrib.viewMode then
self.viewMode = xml.attrib.viewMode
@@ -496,12 +522,18 @@ end
function buildMode:OnFrame(inputEvents)
if self.abortSave and not launch.devMode then
main:SetMode("LIST", self.buildName)
self:CloseBuild()
end
for id, event in ipairs(inputEvents) do
if event.type == "KeyDown" then
if IsKeyDown("CTRL") then
if event.key == "MOUSE4" then
if self.unsaved then
self:OpenSavePopup("LIST")
else
self:CloseBuild()
end
elseif IsKeyDown("CTRL") then
if event.key == "s" then
self:SaveDBFile()
inputEvents[id] = nil
@@ -509,7 +541,7 @@ function buildMode:OnFrame(inputEvents)
if self.unsaved then
self:OpenSavePopup("LIST")
else
main:SetMode("LIST", self.dbFileName and self.buildName)
self:CloseBuild()
end
elseif event.key == "1" then
self.viewMode = "TREE"
@@ -604,65 +636,77 @@ function buildMode:OpenSavePopup(mode)
["EXIT"] = "before exiting?",
["UPDATE"] = "before updating?",
}
main:OpenPopup(290, 100, "Save Changes", {
common.New("LabelControl", nil, 0, 20, 0, 16, "^7This build has unsaved changes.\nDo you want to save them "..modeDesc[mode]),
common.New("ButtonControl", nil, -90, 70, 80, 20, "Save", function()
main:ClosePopup()
self.actionOnSave = mode
self:SaveDBFile()
end),
common.New("ButtonControl", nil, 0, 70, 80, 20, "Don't Save", function()
main:ClosePopup()
if mode == "LIST" then
main:SetMode("LIST", self.dbFileName and self.buildName)
elseif mode == "EXIT" then
Exit()
elseif mode == "UPDATE" then
launch:ApplyUpdate(launch.updateAvailable)
end
end),
common.New("ButtonControl", nil, 90, 70, 80, 20, "Cancel", function()
main:ClosePopup()
end),
})
local controls = { }
controls.label = common.New("LabelControl", nil, 0, 20, 0, 16, "^7This build has unsaved changes.\nDo you want to save them "..modeDesc[mode])
controls.save = common.New("ButtonControl", nil, -90, 70, 80, 20, "Save", function()
main:ClosePopup()
self.actionOnSave = mode
self:SaveDBFile()
end)
controls.noSave = common.New("ButtonControl", nil, 0, 70, 80, 20, "Don't Save", function()
main:ClosePopup()
if mode == "LIST" then
self:CloseBuild()
elseif mode == "EXIT" then
Exit()
elseif mode == "UPDATE" then
launch:ApplyUpdate(launch.updateAvailable)
end
end)
controls.close = common.New("ButtonControl", nil, 90, 70, 80, 20, "Cancel", function()
main:ClosePopup()
end)
main:OpenPopup(290, 100, "Save Changes", controls)
end
function buildMode:OpenSaveAsPopup()
local newFileName, newBuildName
local popup
popup = main:OpenPopup(370, 100, self.dbFileName and "Save As" or "Save", {
common.New("LabelControl", nil, 0, 20, 0, 16, "^7Enter new build name:"),
edit = common.New("EditControl", nil, 0, 40, 350, 20, self.dbFileName and self.buildName, nil, "\\/:%*%?\"<>|%c", 100, function(buf)
newFileName = main.buildPath..buf..".xml"
newBuildName = buf
popup.controls.save.enabled = false
if not buf:match("%S") then
return
end
local controls = { }
local function updateBuildName()
local buf = controls.edit.buf
newFileName = main.buildPath..controls.folder.subPath..buf..".xml"
newBuildName = buf
controls.save.enabled = false
if buf:match("%S") then
local out = io.open(newFileName, "r")
if out then
out:close()
return
else
controls.save.enabled = true
end
popup.controls.save.enabled = true
end),
save = common.New("ButtonControl", nil, -45, 70, 80, 20, "Save", function()
main:ClosePopup()
self.dbFileName = newFileName
self.buildName = newBuildName
main.modeArgs = { newFileName, newBuildName }
self:SaveDBFile()
end),
common.New("ButtonControl", nil, 45, 70, 80, 20, "Cancel", function()
main:ClosePopup()
end),
}, "save", "edit")
popup.controls.save.enabled = false
end
end
controls.label = common.New("LabelControl", nil, 0, 20, 0, 16, "^7Enter new build name:")
controls.edit = common.New("EditControl", nil, 0, 40, 450, 20, self.dbFileName and self.buildName, nil, "\\/:%*%?\"<>|%c", 100, function(buf)
updateBuildName()
end)
controls.folderLabel = common.New("LabelControl", {"TOPLEFT",nil,"TOPLEFT"}, 10, 70, 0, 16, "^7Folder:")
controls.newFolder = common.New("ButtonControl", {"TOPLEFT",nil,"TOPLEFT"}, 100, 67, 94, 20, "New Folder...", function()
main:OpenNewFolderPopup(main.buildPath..controls.folder.subPath, function(newFolderName)
if newFolderName then
controls.folder:OpenFolder(newFolderName)
end
end)
end)
controls.folder = common.New("FolderList", nil, 0, 115, 450, 100, self.dbFileSubPath, function(subPath)
updateBuildName()
end)
controls.save = common.New("ButtonControl", nil, -45, 225, 80, 20, "Save", function()
main:ClosePopup()
self.dbFileName = newFileName
self.buildName = newBuildName
self.dbFileSubPath = controls.folder.subPath
self:SaveDBFile()
end)
controls.save.enabled = false
controls.close = common.New("ButtonControl", nil, 45, 225, 80, 20, "Cancel", function()
main:ClosePopup()
end)
main:OpenPopup(470, 255, self.dbFileName and "Save As" or "Save", controls, "save", "edit")
end
-- Open the spectre library popup
function buildMode:OpenSpectreLibrary()
local controls = { }
local destList = copyTable(self.spectreList)
local sourceList = { }
for id in pairs(data.spectres) do
@@ -675,6 +719,7 @@ function buildMode:OpenSpectreLibrary()
return data.minions[a].name < data.minions[b].name
end
end)
local controls = { }
controls.list = common.New("MinionList", nil, -100, 40, 190, 250, destList)
controls.source = common.New("MinionList", nil, 100, 40, 190, 250, sourceList, controls.list)
controls.save = common.New("ButtonControl", nil, -45, 300, 80, 20, "Save", function()
@@ -950,7 +995,7 @@ function buildMode:SaveDBFile()
file:write(xmlText)
file:close()
if self.actionOnSave == "LIST" then
main:SetMode("LIST", self.dbFileName and self.buildName)
self:CloseBuild()
elseif self.actionOnSave == "EXIT" then
Exit()
elseif self.actionOnSave == "UPDATE" then

View File

@@ -7,6 +7,7 @@ local launch, main = ...
local pairs = pairs
local ipairs = ipairs
local t_insert = table.insert
local buildSortDropList = {
{ label = "Sort by Name", sortMode = "NAME" },
@@ -16,18 +17,31 @@ local buildSortDropList = {
local listMode = common.New("ControlHost")
function listMode:Init(selBuildName)
function listMode:Init(selBuildName, subPath)
if self.initialised then
self.subPath = subPath or self.subPath
self.controls.buildList.controls.path:SetSubPath(self.subPath)
self.controls.buildList:SelByFileName(selBuildName and selBuildName..".xml")
self:BuildList()
self:SelectControl(self.controls.buildList)
return
end
self.anchor = common.New("Control", nil, 0, 4, 0, 0)
self.anchor.x = function()
return main.screenW / 2
end
self.subPath = subPath or ""
self.list = { }
self.controls.new = common.New("ButtonControl", {"TOP",self.anchor,"TOP"}, -210, 0, 60, 20, "New", function()
self.controls.new = common.New("ButtonControl", {"TOP",self.anchor,"TOP"}, -259, 0, 60, 20, "New", function()
main:SetMode("BUILD", false, "Unnamed build")
end)
self.controls.open = common.New("ButtonControl", {"LEFT",self.controls.new,"RIGHT"}, 8, 0, 60, 20, "Open", function()
self.controls.newFolder = common.New("ButtonControl", {"LEFT",self.controls.new,"RIGHT"}, 8, 0, 90, 20, "New Folder", function()
self.controls.buildList:NewFolder()
end)
self.controls.open = common.New("ButtonControl", {"LEFT",self.controls.newFolder,"RIGHT"}, 8, 0, 60, 20, "Open", function()
self.controls.buildList:LoadBuild(self.controls.buildList.selValue)
end)
self.controls.open.enabled = function() return self.controls.buildList.selValue ~= nil end
@@ -48,21 +62,63 @@ function listMode:Init(selBuildName)
self:SortList()
end)
self.controls.sort:SelByValue(main.buildSortMode, "sortMode")
self.controls.buildList = common.New("BuildList", {"TOP",self.anchor,"TOP"}, 0, 24, 640, 0, self)
self.controls.buildList = common.New("BuildList", {"TOP",self.anchor,"TOP"}, 0, 50, 640, 0, self)
self.controls.buildList.height = function()
return main.screenH - 32
return main.screenH - 58
end
self:BuildList()
self.controls.buildList:SelByFileName(selBuildName and selBuildName..".xml")
self:SelectControl(self.controls.buildList)
self.initialised = true
end
function listMode:Shutdown()
end
function listMode:GetArgs()
return self.controls.buildList.selValue and self.controls.buildList.selValue.buildName or false, self.subPath
end
function listMode:OnFrame(inputEvents)
for id, event in ipairs(inputEvents) do
if event.type == "KeyDown" then
if event.key == "v" and IsKeyDown("CTRL") then
if self.controls.buildList.copyBuild then
local build = self.controls.buildList.copyBuild
if build.subPath ~= self.subPath then
if build.folderName then
main:CopyFolder(build.folderName, main.buildPath..build.subPath, main.buildPath..self.subPath)
else
copyFile(build.fullFileName, self:GetDestName(self.subPath, build.fileName))
end
self:BuildList()
else
self.controls.buildList:RenameBuild(build, true)
end
self.controls.buildList.copyBuild = nil
elseif self.controls.buildList.cutBuild then
local build = self.controls.buildList.cutBuild
if build.subPath ~= self.subPath then
if build.folderName then
main:MoveFolder(build.folderName, main.buildPath..build.subPath, main.buildPath..self.subPath)
else
os.rename(build.fullFileName, self:GetDestName(self.subPath, build.fileName))
end
self:BuildList()
end
self.controls.buildList.cutBuild = nil
end
elseif event.key == "n" and IsKeyDown("CTRL") then
main:SetMode("BUILD", false, "Unnamed build")
elseif event.key == "MOUSE4" then
self.controls.buildList.controls.path:Undo()
elseif event.key == "MOUSE5" then
self.controls.buildList.controls.path:Redo()
end
end
end
self:ProcessControlsInput(inputEvents, main.viewPort)
main:DrawBackground(main.viewPort)
@@ -70,19 +126,33 @@ function listMode:OnFrame(inputEvents)
self:DrawControls(main.viewPort)
end
function listMode:BuildList()
self.list = wipeTable(self.list)
local handle = NewFileSearch(main.buildPath.."*.xml")
if not handle then
return
end
function listMode:GetDestName(subPath, fileName)
local i = 2
local destName = fileName
while true do
local test = io.open(destName, "r")
if test then
destName = fileName .. "[" .. i .. "]"
i = i + 1
else
break
end
end
return main.buildPath..subPath..destName
end
function listMode:BuildList()
wipeTable(self.list)
local handle = NewFileSearch(main.buildPath..self.subPath.."*.xml")
while handle do
local fileName = handle:GetFileName()
local build = { }
build.fileName = fileName
build.subPath = self.subPath
build.fullFileName = main.buildPath..self.subPath..fileName
build.modified = handle:GetFileModifiedTime()
build.buildName = fileName:gsub("%.xml$","")
local dbXML = common.xml.LoadXMLFile(main.buildPath..fileName)
local dbXML = common.xml.LoadXMLFile(build.fullFileName)
if dbXML and dbXML[1].elem == "PathOfBuilding" then
for _, node in ipairs(dbXML[1]) do
if type(node) == "table" and node.elem == "Build" then
@@ -92,7 +162,19 @@ function listMode:BuildList()
end
end
end
table.insert(self.list, build)
t_insert(self.list, build)
if not handle:NextFile() then
break
end
end
handle = NewFileSearch(main.buildPath..self.subPath.."*", true)
while handle do
local folderName = handle:GetFileName()
t_insert(self.list, {
folderName = folderName,
subPath = self.subPath,
fullFileName = main.buildPath..self.subPath..folderName,
})
if not handle:NextFile() then
break
end
@@ -103,6 +185,13 @@ end
function listMode:SortList()
local oldSelFileName = self.controls.buildList.selValue and self.controls.buildList.selValue.fileName
table.sort(self.list, function(a, b)
if a.folderName and b.folderName then
return a.folderName:upper() < b.folderName:upper()
elseif a.folderName and not b.folderName then
return true
elseif not a.folderName and b.folderName then
return false
end
if main.buildSortMode == "EDITED" then
return a.modified > b.modified
elseif main.buildSortMode == "CLASS" then

View File

@@ -294,3 +294,17 @@ function getFormatSec(dec)
end
end
function copyFile(srcName, dstName)
local inFile, msg = io.open(srcName, "r")
if not inFile then
return nil, "Couldn't open '"..srcName.."': "..msg
end
local outFile, msg = io.open(dstName, "w")
if not outFile then
return nil, "Couldn't create '"..dstName.."': "..msg
end
outFile:write(inFile:read("*a"))
inFile:close()
outFile:close()
return true
end

View File

@@ -342,26 +342,30 @@ function itemLib.parseItemRaw(item)
end
item.affixLimit = 0
if item.crafted then
if item.rarity == "MAGIC" then
if not item.affixes then
item.crafted = false
elseif item.rarity == "MAGIC" then
item.affixLimit = 2
elseif item.rarity == "RARE" then
item.affixLimit = (item.base.type == "Jewel" and 4 or 6)
item.affixLimit = (item.type == "Jewel" and 4 or 6)
else
item.crafted = false
end
for _, list in ipairs({item.prefixes,item.suffixes}) do
for i = 1, item.affixLimit/2 do
if not list[i] then
list[i] = "None"
elseif list[i] ~= "None" and not item.affixes[list[i]] then
for modId, mod in pairs(item.affixes) do
if list[i] == mod.affix then
list[i] = modId
break
end
end
if not item.affixes[list[i]] then
if item.crafted then
for _, list in ipairs({item.prefixes,item.suffixes}) do
for i = 1, item.affixLimit/2 do
if not list[i] then
list[i] = "None"
elseif list[i] ~= "None" and not item.affixes[list[i]] then
for modId, mod in pairs(item.affixes) do
if list[i] == mod.affix then
list[i] = modId
break
end
end
if not item.affixes[list[i]] then
list[i] = "None"
end
end
end
end
@@ -544,9 +548,6 @@ function itemLib.craftItem(item)
for _, line in ipairs(custom) do
t_insert(item.modLines, line)
end
if item.rarity == "MAGIC" then
item.name = newName
end
item.raw = itemLib.createItemRaw(item)
itemLib.parseItemRaw(item)
end

View File

@@ -39,10 +39,12 @@ local classList = {
"SliderControl",
"TextListControl",
"ListControl",
"PathControl",
-- Misc
"PopupDialog",
-- Mode: Build list
"BuildListControl",
"FolderListControl",
-- Mode: Build
"ModList",
"ModDB",
@@ -230,9 +232,8 @@ function main:OnFrame()
self:CallMode("Shutdown")
end
self.mode = self.newMode
self.modeArgs = self.newModeArgs
self.newMode = nil
self:CallMode("Init", unpack(self.modeArgs))
self:CallMode("Init", unpack(self.newModeArgs))
end
self.viewPort = { x = 0, y = 0, width = self.screenW, height = self.screenH }
@@ -411,7 +412,7 @@ end
function main:SaveSettings()
local setXML = { elem = "PathOfBuilding" }
local mode = { elem = "Mode", attrib = { mode = self.mode } }
for _, val in ipairs(self.modeArgs) do
for _, val in ipairs({ self:CallMode("GetArgs") }) do
local child = { elem = "Arg", attrib = { } }
if type(val) == "number" then
child.attrib.number = tostring(val)
@@ -664,6 +665,82 @@ function main:StatColor(stat, base, limit)
end
end
function main:MoveFolder(name, srcPath, dstPath)
-- Create destination folder
local res, msg = MakeDir(dstPath..name)
if not res then
self:OpenMessagePopup("Error", "Couldn't move '"..name.."' to '"..dstPath.."' : "..msg)
return
end
-- Move subfolders
local handle = NewFileSearch(srcPath..name.."/*", true)
while handle do
self:MoveFolder(handle:GetFileName(), srcPath..name.."/", dstPath..name.."/")
if not handle:NextFile() then
break
end
end
-- Move files
handle = NewFileSearch(srcPath..name.."/*")
while handle do
local fileName = handle:GetFileName()
local srcName = srcPath..name.."/"..fileName
local dstName = dstPath..name.."/"..fileName
local res, msg = os.rename(srcName, dstName)
if not res then
self:OpenMessagePopup("Error", "Couldn't move '"..srcName.."' to '"..dstName.."': "..msg)
return
end
if not handle:NextFile() then
break
end
end
-- Remove source folder
local res, msg = RemoveDir(srcPath..name)
if not res then
self:OpenMessagePopup("Error", "Couldn't delete '"..dstPath..name.."' : "..msg)
return
end
end
function main:CopyFolder(srcName, dstName)
-- Create destination folder
local res, msg = MakeDir(dstName)
if not res then
self:OpenMessagePopup("Error", "Couldn't copy '"..srcName.."' to '"..dstName.."' : "..msg)
return
end
-- Copy subfolders
local handle = NewFileSearch(srcName.."/*", true)
while handle do
local fileName = handle:GetFileName()
self:CopyFolder(srcName.."/"..fileName, dstName.."/"..fileName)
if not handle:NextFile() then
break
end
end
-- Copy files
handle = NewFileSearch(srcName.."/*")
while handle do
local fileName = handle:GetFileName()
local srcName = srcName.."/"..fileName
local dstName = dstName.."/"..fileName
local res, msg = copyFile(srcName, dstName)
if not res then
self:OpenMessagePopup("Error", "Couldn't copy '"..srcName.."' to '"..dstName.."': "..msg)
return
end
if not handle:NextFile() then
break
end
end
end
function main:OpenPopup(width, height, title, controls, enterControl, defaultControl, escapeControl)
local popup = common.New("PopupDialog", width, height, title, controls, enterControl, defaultControl, escapeControl)
t_insert(self.popups, 1, popup)
@@ -704,6 +781,34 @@ function main:OpenConfirmPopup(title, msg, confirmLabel, onConfirm)
return self:OpenPopup(m_max(DrawStringWidth(16, "VAR", msg) + 30, 190), 70 + numMsgLines * 16, title, controls, "confirm")
end
function main:OpenNewFolderPopup(path, onClose)
local controls = { }
controls.label = common.New("LabelControl", nil, 0, 20, 0, 16, "^7Enter folder name:")
controls.edit = common.New("EditControl", nil, 0, 40, 350, 20, nil, nil, "\\/:%*%?\"<>|%c", 100, function(buf)
controls.create.enabled = buf:match("%S")
end)
controls.create = common.New("ButtonControl", nil, -45, 70, 80, 20, "Create", function()
local newFolderName = controls.edit.buf
local res, msg = MakeDir(path..newFolderName)
if not res then
main:OpenMessagePopup("Error", "Couldn't create '"..newFolderName.."': "..msg)
return
end
if onClose then
onClose(newFolderName)
end
main:ClosePopup()
end)
controls.create.enabled = false
controls.cancel = common.New("ButtonControl", nil, 45, 70, 80, 20, "Cancel", function()
if onClose then
onClose()
end
main:ClosePopup()
end)
main:OpenPopup(370, 100, "New Folder", controls, "create", "edit", "cancel")
end
do
local wrapTable = { }
function main:WrapString(str, height, width)

View File

@@ -69,6 +69,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Classes", "Classes", "{7EE4
Classes\ControlHost.lua = Classes\ControlHost.lua
Classes\DropDownControl.lua = Classes\DropDownControl.lua
Classes\EditControl.lua = Classes\EditControl.lua
Classes\FolderListControl.lua = Classes\FolderListControl.lua
Classes\GemSelectControl.lua = Classes\GemSelectControl.lua
Classes\ImportTab.lua = Classes\ImportTab.lua
Classes\ItemDBControl.lua = Classes\ItemDBControl.lua
@@ -85,6 +86,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Classes", "Classes", "{7EE4
Classes\PassiveSpecListControl.lua = Classes\PassiveSpecListControl.lua
Classes\PassiveTree.lua = Classes\PassiveTree.lua
Classes\PassiveTreeView.lua = Classes\PassiveTreeView.lua
Classes\PathControl.lua = Classes\PathControl.lua
Classes\PopupDialog.lua = Classes\PopupDialog.lua
Classes\ScrollBarControl.lua = Classes\ScrollBarControl.lua
Classes\SectionControl.lua = Classes\SectionControl.lua

View File

@@ -53,6 +53,11 @@ If you'd like to help support the development of Path of Building, I have a [Pat
![ss3](https://cloud.githubusercontent.com/assets/19189971/18089780/f0ff234a-6f04-11e6-8c88-6193fe59a5c4.png)
## Changelog
### 1.4.19 - 2017/06/07
* The build list now has support for folders
* Importing from a build code no longer requires you to name the build before importing
* Fixed an error that could appear while using the item text editor
### 1.4.18 - 2017/06/03
* The "Craft item..." feature has been significantly enhanced:
* Modifiers are now available for all item types, not just Flasks and Jewels

View File

@@ -1,3 +1,7 @@
VERSION[1.4.19][2017/06/07]
* The build list now has support for folders
* Importing from a build code no longer requires you to name the build before importing
* Fixed an error that could appear while using the item text editor
VERSION[1.4.18][2017/06/03]
* The "Craft item..." feature has been significantly enhanced:
* Modifiers are now available for all item types, not just Flasks and Jewels

View File

@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<PoBVersion>
<Version number="1.4.18"/>
<Version number="1.4.19"/>
<Source part="program" url="https://raw.githubusercontent.com/Openarl/PathOfBuilding/{branch}/"/>
<Source part="tree" url="https://raw.githubusercontent.com/Openarl/PathOfBuilding/{branch}/tree.zip"/>
<Source url="https://raw.githubusercontent.com/Openarl/PathOfBuilding/{branch}/runtime-win32.zip" part="runtime" platform="win32"/>
<File sha1="2fb719ed2a9648b2dd13a137f650b3c0e48705fa" name="Launch.lua" part="program"/>
<File sha1="72b9bea1871e94a643e4471fd84bbedbc7810336" name="UpdateCheck.lua" part="program"/>
<File sha1="4f17937f2b37784e169a3792b235f2a0a3961e61" name="UpdateApply.lua" part="program"/>
<File sha1="cf11d72447d87e92f0583dd8c339990ffb69713c" name="changelog.txt" part="program"/>
<File sha1="3ff73a3c46cb7bd8a53c9d47a893dd2b4c5c60ab" name="Classes/BuildListControl.lua" part="program"/>
<File sha1="092230817cfaa0253f9626c13fec538833320ed2" name="changelog.txt" part="program"/>
<File sha1="2e17b80ed729017d9f428ddb8f6f865096cd2ab0" name="Classes/BuildListControl.lua" part="program"/>
<File sha1="dc2ffb55b4aae04b86886b25bbf219a301b21340" name="Classes/ButtonControl.lua" part="program"/>
<File sha1="9391d403c4ad8e59fd02fba76158acb4159e0562" name="Classes/CalcBreakdownControl.lua" part="program"/>
<File sha1="f7bced0e554bd4d99ef56bd87cf43294957cd179" name="Classes/CalcSectionControl.lua" part="program"/>
@@ -19,14 +19,15 @@
<File sha1="45be3d636d1eaff18bed7095478c22abfd0590ef" name="Classes/ControlHost.lua" part="program"/>
<File sha1="66486b0b9e628bb450a080f0e81aa48256d76f6c" name="Classes/DropDownControl.lua" part="program"/>
<File sha1="276512f60a6634a1c4febd475fe1e280b81b23b4" name="Classes/EditControl.lua" part="program"/>
<File sha1="afa58b85c876e107edcd49e4a01c06a981843ff8" name="Classes/FolderListControl.lua" part="program"/>
<File sha1="e08d917e46b196ec664b380efc738aec4bfc6ce4" name="Classes/GemSelectControl.lua" part="program"/>
<File sha1="9b405a28c6e943234bbc7a0f26da0509b8a090e4" name="Classes/ImportTab.lua" part="program"/>
<File sha1="1a097633cbd64c7b607327e3601d8132269f540e" name="Classes/ImportTab.lua" part="program"/>
<File sha1="c776a638847555b8500f7c8d94eb825667d66dad" name="Classes/ItemDBControl.lua" part="program"/>
<File sha1="6f289bf6318303831c3acafc35d37fe2b90e6609" name="Classes/ItemListControl.lua" part="program"/>
<File sha1="7b4df976743a6b4833525997a982da17bc257cd2" name="Classes/ItemSlotControl.lua" part="program"/>
<File sha1="0fd16362d7a5f34cd2174373e784b8277440d867" name="Classes/ItemsTab.lua" part="program"/>
<File sha1="62138c7db82d57d638a16610a26acd0de75d3486" name="Classes/LabelControl.lua" part="program"/>
<File sha1="015e7f6092cd978399956bd05d545fe45bca81d6" name="Classes/ListControl.lua" part="program"/>
<File sha1="ab8b2ba2fa22b67212ea706907920491f39b7f50" name="Classes/ListControl.lua" part="program"/>
<File sha1="75c943489d007c34793f6568c28cee2bc1843e75" name="Classes/MinionListControl.lua" part="program"/>
<File sha1="4cc00763fe60eb073a89e930693aaaec29bb12ab" name="Classes/ModDB.lua" part="program"/>
<File sha1="e3bf78751f622edde53d6c595451077a8d0a5218" name="Classes/ModList.lua" part="program"/>
@@ -35,6 +36,7 @@
<File sha1="2802110b05a2ebdf39e62c1e9cfcf72d9538f359" name="Classes/PassiveSpecListControl.lua" part="program"/>
<File sha1="bcd74b6409a4d39d27b2f4db8106daf763d97f47" name="Classes/PassiveTree.lua" part="program"/>
<File sha1="7c39162f10b7770c4e4f560470d7a1132cdd7ef6" name="Classes/PassiveTreeView.lua" part="program"/>
<File sha1="824082f62de7fa5fbe9ea95ee59db8bb6e378b5f" name="Classes/PathControl.lua" part="program"/>
<File sha1="9d91ef81ac4fd8d5a1e16be17bdf199545209d87" name="Classes/PopupDialog.lua" part="program"/>
<File sha1="86fee3127d9520144fc741f6fccc3c1d9f1aa532" name="Classes/ScrollBarControl.lua" part="program"/>
<File sha1="261dcf54a4542e6160fd7024d8edf4fc095d9c71" name="Classes/SectionControl.lua" part="program"/>
@@ -45,8 +47,8 @@
<File sha1="ada27b91a3c466689111429105edd4ee28ad0c3f" name="Classes/TextListControl.lua" part="program"/>
<File sha1="5937806febd0a2613f441080af9256babe25b2cc" name="Classes/TreeTab.lua" part="program"/>
<File sha1="4b7675c8b4fe71cade7dd3d70793df1ed8022d01" name="Classes/UndoHandler.lua" part="program"/>
<File sha1="460befa5e7572a54d00167dccba58a19a2766a79" name="Modules/Build.lua" part="program"/>
<File sha1="74e5b2dec4b28b7fc118cedd64640c96ffe2bb67" name="Modules/BuildList.lua" part="program"/>
<File sha1="c668c8e029526b84e42c28a8ddfaa2c7ec87906a" name="Modules/Build.lua" part="program"/>
<File sha1="44fab56072de8e555ff7e20ee32628230511d1d6" name="Modules/BuildList.lua" part="program"/>
<File sha1="543b9e61daf948e9236592966905e7092fce81ca" name="Modules/CalcActiveSkill.lua" part="program"/>
<File sha1="b2b8d55258d9763d7c7a4a9ca1f99be3973528a8" name="Modules/CalcBreakdown.lua" part="program"/>
<File sha1="8647664477fef0e771500b96342496c83ab3fe4f" name="Modules/CalcDefence.lua" part="program"/>
@@ -56,10 +58,10 @@
<File sha1="a5e8d848cb24a7f0920c287e0c05f01bfaab88ef" name="Modules/CalcSections.lua" part="program"/>
<File sha1="7fa850d6ef731394282750d07780cc3b26119f49" name="Modules/CalcSetup.lua" part="program"/>
<File sha1="8966118c2bbaacf0e870d9765d6c3c485ffd88d8" name="Modules/CalcTools.lua" part="program"/>
<File sha1="1a3f16372f27e7b94d373e6c61affb4ebe478b13" name="Modules/Common.lua" part="program"/>
<File sha1="d103281d8289bc3897ac855921e15136c1cda0cf" name="Modules/Common.lua" part="program"/>
<File sha1="a2002eded5f44fe7fdce74bd239fcfa9760506e7" name="Modules/Data.lua" part="program"/>
<File sha1="0b5474d73ca754677844340cb64f648f59cbc061" name="Modules/ItemTools.lua" part="program"/>
<File sha1="4e2165230dacd9f22f21d0fe06b6754b89e68a7f" name="Modules/Main.lua" part="program"/>
<File sha1="b0dbeb73dab718c291ce4407cf7c26ce67fe69b7" name="Modules/ItemTools.lua" part="program"/>
<File sha1="19f39029cdf75b8a773f431de8f697ecba8f14ce" name="Modules/Main.lua" part="program"/>
<File sha1="5bd9ad19b4c367ce605dba883126a46015a8d393" name="Modules/ModParser.lua" part="program"/>
<File sha1="08bfd94f291b10dbdc75c94d7f2928c8bbd1a1d7" name="Modules/ModTools.lua" part="program"/>
<File sha1="c345cdcf374d271411aa424ab150c0edbb5a362d" name="Assets/game_ui_small.png" part="program"/>
@@ -123,7 +125,7 @@
<File sha1="9b2be22e3f644da45e432d445d9515d64b2261ee" name="Data/Uniques/mace.lua" part="program"/>
<File sha1="940ec4e40778144151a611400174ed79b813c204" name="Data/Uniques/quiver.lua" part="program"/>
<File sha1="3ec41f8199a0c1d3e9376fac864d51e45d10f1e4" name="Data/Uniques/ring.lua" part="program"/>
<File sha1="3f872490e7f95c4f2e6933605d5142edf74c67e6" name="Data/Uniques/shield.lua" part="program"/>
<File sha1="939f96fe7b24783b88c6c2e88cffd6f7c5798efd" name="Data/Uniques/shield.lua" part="program"/>
<File sha1="d766b31e772fa6346d80561e22dfe53ab86c70f6" name="Data/Uniques/staff.lua" part="program"/>
<File sha1="9c80b708d7060b0174c906157b18bf7ca82fdf93" name="Data/Uniques/sword.lua" part="program"/>
<File sha1="b4611a28551b3480d0886c624b81242c9cdae6f2" name="Data/Uniques/wand.lua" part="program"/>