Skip to content
392 changes: 392 additions & 0 deletions spec/System/TestLoadouts_spec.lua

Large diffs are not rendered by default.

217 changes: 217 additions & 0 deletions src/Classes/BuildSetListControl.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
-- Path of Building
--
-- Class: Build Set List
-- Build set list control.
--
local t_insert = table.insert
local t_remove = table.remove

local BuildSetListClass = newClass("BuildSetListControl", "ListControl", function(self, anchor, rect, buildMode)
self.ListControl(anchor, rect, 16, "VERTICAL", true, buildMode.treeTab.specList)
self.buildMode = buildMode
self.buildSetService = new("BuildSetService", buildMode)
self.controls.new = new("ButtonControl", { "BOTTOMLEFT", self, "TOP" }, { -190, -4, 60, 18 }, "New",
function()
self:NewLoadout()
end)
self.controls.rename = new("ButtonControl", { "LEFT", self.controls.new, "RIGHT" }, { 5, 0, 60, 18 }, "Rename", function()
self:RenameLoadout(self.selValue)
end)
self.controls.rename.enabled = function()
return self.selValue ~= nil
end
self.controls.copy = new("ButtonControl", { "LEFT", self.controls.rename, "RIGHT" }, { 5, 0, 60, 18 }, "Copy", function()
local loadoutNameToCopy = self.selValue.title or "Default"
local build = buildMode:GetLoadoutByName(loadoutNameToCopy)
self:CopyLoadoutClick(build)
end)
self.controls.copy.enabled = function()
return self.selValue ~= nil
end
self.controls.delete = new("ButtonControl", { "LEFT", self.controls.copy, "RIGHT" }, { 5, 0, 60, 18 }, "Delete",
function()
self:OnSelDelete(self.selIndex, self.selValue)
end)
self.controls.delete.enabled = function()
return self.selValue ~= nil and #self.list > 1
end
self.controls.custom = new("ButtonControl", { "LEFT", self.controls.delete, "RIGHT" }, { 5, 0, 120, 18 },
"New/Copy Custom",
function()
if self.selValue == nil then
self:CopyCustom({
specId = 0,
itemSetId = 0,
skillSetId = 0,
configSetId = 0,
})
else
local loadoutNameToCopy = self.selValue.title or "Default"
local build = buildMode:GetLoadoutByName(loadoutNameToCopy)
self:CopyCustom(build)
end
end)
end)

function BuildSetListClass:RenameLoadout(spec)
local controls = {}
local specName = spec.title or "Default"
controls.label = new("LabelControl", nil, { 0, 20, 0, 16 }, "^7Enter name for this loadout:")
controls.edit = new("EditControl", nil, { 0, 40, 350, 20 }, specName, nil, nil, 100, function(buf)
controls.save.enabled = buf:match("%S")
end)
controls.save = new("ButtonControl", nil, { -45, 70, 80, 20 }, "Save", function()
local newTitle = controls.edit.buf
self.buildSetService:RenameLoadout(specName, newTitle)
main:ClosePopup()
end)
controls.save.enabled = false
controls.cancel = new("ButtonControl", nil, { 45, 70, 80, 20 }, "Cancel", function()
main:ClosePopup()
end)
main:OpenPopup(370, 100, specName and "Rename Loadout" or "Set Name", controls, "save", "edit", "cancel")
end

function BuildSetListClass:CopyLoadoutClick(build)
local controls = {}
local buildName = self.buildMode.treeTab.specList[build.specId].title
controls.label = new("LabelControl", nil, { 0, 20, 0, 16 }, "^7Enter name for this loadout:")
controls.edit = new("EditControl", nil, { 0, 40, 350, 20 }, buildName, nil, nil, 100, function(buf)
controls.save.enabled = buf:match("%S")
end)
controls.save = new("ButtonControl", nil, { -45, 70, 80, 20 }, "Save", function()
self.buildSetService:CopyLoadout(build.specId, build.itemSetId, build.skillSetId, build.configSetId,
controls.edit.buf)
main:ClosePopup()
end)
controls.save.enabled = false
controls.cancel = new("ButtonControl", nil, { 45, 70, 80, 20 }, "Cancel", function()
main:ClosePopup()
end)
main:OpenPopup(370, 100, buildName and "Rename" or "Set Name", controls, "save", "edit", "cancel")
end

function BuildSetListClass:CopyCustom(build)
local function getList(setList, orderList, activeId)
local newSetList = { "^7New" }
local activeIndex = 1
for index, setId in ipairs(orderList) do
local set = setList[setId]
t_insert(newSetList, set.title or "Default")
if setId == activeId then
activeIndex = index + 1
end
end
return newSetList, activeIndex
end
local controls = {}
local buildName = build.specId > 0 and self.buildMode.treeTab.specList[build.specId].title or "New Loadout"
controls.label = new("LabelControl", nil, { 0, 20, 0, 16 }, "^7Enter name for this loadout:")
controls.edit = new("EditControl", nil, { 0, 40, 350, 20 }, buildName, nil, nil, 100, function(buf)
controls.save.enabled = buf:match("%S")
end)

local treeList = self.buildMode.treeTab:GetSpecList()
t_insert(treeList, 1, "^7New")
controls.treeDropDown = new("DropDownControl", nil, { 0, 90, 350, 20 }, treeList, function(index)

end)
controls.treeDropDown:SetSel(build.specId + 1)
controls.treeLabel = new("LabelControl", { "BOTTOMLEFT", controls.treeDropDown, "TOPLEFT" }, { 4, -4, 0, 16 },
"^7Copy from Tree:")

local skillList, activeSkillIndex = getList(self.buildMode.skillsTab.skillSets,
self.buildMode.skillsTab.skillSetOrderList, build.skillSetId)
controls.skillDropDown = new("DropDownControl", nil, { 0, 140, 350, 20 }, skillList, function(index)

end)
controls.skillDropDown:SetSel(activeSkillIndex)
controls.skillLabel = new("LabelControl", { "BOTTOMLEFT", controls.skillDropDown, "TOPLEFT" }, { 4, -4, 0, 16 },
"^7Copy from Skill Set:")

local itemList, activeItemIndex = getList(self.buildMode.itemsTab.itemSets, self.buildMode.itemsTab.itemSetOrderList,
build.itemSetId)
controls.itemDropDown = new("DropDownControl", nil, { 0, 190, 350, 20 }, itemList, function(index)

end)
controls.itemDropDown:SetSel(activeItemIndex)
controls.itemLabel = new("LabelControl", { "BOTTOMLEFT", controls.itemDropDown, "TOPLEFT" }, { 4, -4, 0, 16 },
"^7Copy from Item Set:")

local configList, activeConfigIndex = getList(self.buildMode.configTab.configSets,
self.buildMode.configTab.configSetOrderList, build.configSetId)
controls.configDropDown = new("DropDownControl", nil, { 0, 240, 350, 20 }, configList, function(index)

end)
controls.configDropDown:SetSel(activeConfigIndex)
controls.configLabel = new("LabelControl", { "BOTTOMLEFT", controls.configDropDown, "TOPLEFT" }, { 4, -4, 0, 16 },
"^7Copy from Config Set:")

controls.save = new("ButtonControl", nil, { -45, 270, 80, 20 }, "Save", function()
self.buildSetService:CopyLoadout(build.specId, build.itemSetId, build.skillSetId, build.configSetId,
controls.edit.buf)
main:ClosePopup()
end)
controls.save.enabled = false
controls.cancel = new("ButtonControl", nil, { 45, 270, 80, 20 }, "Cancel", function()
main:ClosePopup()
end)
main:OpenPopup(370, 300, "Create Custom Loadout", controls, "save", "edit", "cancel")
end

function BuildSetListClass:NewLoadout()
local controls = {}
controls.label = new("LabelControl", nil, { 0, 20, 0, 16 }, "^7Enter name for this loadout:")
controls.edit = new("EditControl", nil, { 0, 40, 350, 20 }, "New Loadout", nil, nil, 100, function(buf)
controls.save.enabled = buf:match("%S")
end)
controls.save = new("ButtonControl", nil, { -45, 70, 80, 20 }, "Save", function()
self.buildSetService:NewLoadout(controls.edit.buf)
main:ClosePopup()
end)
controls.save.enabled = false
controls.cancel = new("ButtonControl", nil, { 45, 70, 80, 20 }, "Cancel", function()
main:ClosePopup()
end)
main:OpenPopup(370, 100, "Set Name", controls, "save", "edit", "cancel")
end

function BuildSetListClass:GetRowValue(column, index, spec)
if column == 1 then
local used = spec:CountAllocNodes()
return (spec.treeVersion ~= latestTreeVersion and ("[" .. treeVersions[spec.treeVersion].display .. "] ") or "")
.. (spec.title or "Default")
..
" (" ..
(spec.curAscendClassName ~= "None" and spec.curAscendClassName or spec.curClassName) ..
", " .. used .. " points)"
.. (index == self.buildMode.treeTab.activeSpec and " ^9(Current)" or "")
end
end

function BuildSetListClass:OnOrderChange()
self.buildMode.modFlag = true
end

function BuildSetListClass:OnSelClick(index, spec, doubleClick)
if doubleClick and index ~= self.buildMode.treeTab.activeSpec then
self.buildMode.controls.buildLoadouts:SetSel(index + 1)
end
end

function BuildSetListClass:OnSelDelete(index, spec)
if #self.list > 1 then
main:OpenConfirmPopup("Delete Loadout", "Are you sure you want to delete '" .. (spec.title or "Default") .. "'?",
"Delete", function()
self.buildSetService:DeleteLoadout(index, self.list, spec)
self.selIndex = nil
self.selValue = nil
end)
end
end

function BuildSetListClass:OnSelKeyDown(index, spec, key)
if key == "F2" then
self:RenameLoadout(spec)
end
end
38 changes: 38 additions & 0 deletions src/Classes/BuildSetService.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-- Path of Building
--
-- Module: BuildSetService
-- Build set service for managing loadouts.

-- Utility functions
local m_max = math.max


local BuildSetServiceClass = newClass("BuildSetService", function(self, buildMode)
self.buildMode = buildMode
end)

function BuildSetServiceClass:NewLoadout(name)
self.buildMode:NewLoadout(name, function()
self.buildMode:SyncLoadouts()
self.buildMode.controls.buildLoadouts:SetSel(1)
end)
end

function BuildSetServiceClass:CopyLoadout(specId, itemSetId, skillSetId, configSetId, newName)
local newSpec = self.buildMode:CopyLoadout(specId, itemSetId, skillSetId, configSetId, newName)
self.buildMode:SyncLoadouts()
self.buildMode.controls.buildLoadouts:SetSel(newSpec.id + 1)
end

function BuildSetServiceClass:RenameLoadout(oldName, newName)
self.buildMode:RenameLoadout(oldName, newName, function()
self.buildMode:SyncLoadouts()
end)
end

function BuildSetServiceClass:DeleteLoadout(index, list, spec)
local nextLoadoutIndex = index == self.buildMode.treeTab.activeSpec and (index > 1 and index - 1 or index + 1) or
self.buildMode.treeTab.activeSpec
local nextLoadout = list[nextLoadoutIndex]
self.buildMode:DeleteLoadout(spec.title or "Default", nextLoadout.title or "Default")
end
8 changes: 1 addition & 7 deletions src/Classes/ConfigSetListControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,7 @@ local ConfigSetListClass = newClass("ConfigSetListControl", "ListControl", funct
self.ListControl(anchor, rect, 16, "VERTICAL", true, configTab.configSetOrderList)
self.configTab = configTab
self.controls.copy = new("ButtonControl", {"BOTTOMLEFT",self,"TOP"}, {2, -4, 60, 18}, "Copy", function()
local configSet = configTab.configSets[self.selValue]
local newConfigSet = copyTable(configSet)
newConfigSet.id = 1
while configTab.configSets[newConfigSet.id] do
newConfigSet.id = newConfigSet.id + 1
end
configTab.configSets[newConfigSet.id] = newConfigSet
local newConfigSet = configTab:CopyConfigSet(self.selValue)
self:RenameSet(newConfigSet, true)
end)
self.controls.copy.enabled = function()
Expand Down
21 changes: 15 additions & 6 deletions src/Classes/ConfigTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
-- Configuration tab for the current build.
--
local t_insert = table.insert
local t_maxn = table.maxn
local m_min = math.min
local m_max = math.max
local m_floor = math.floor
Expand Down Expand Up @@ -958,10 +959,7 @@ end
function ConfigTabClass:NewConfigSet(configSetId, title)
local configSet = { id = configSetId, title = title, input = { }, placeholder = { } }
if not configSetId then
configSet.id = 1
while self.configSets[configSet.id] do
configSet.id = configSet.id + 1
end
configSet.id = #self.configSets + 1
end
-- there are default values for input and placeholder that every new config set needs to have
for _, varData in ipairs(varList) do
Expand All @@ -977,8 +975,17 @@ function ConfigTabClass:NewConfigSet(configSetId, title)
return configSet
end

function ConfigTabClass:CopyConfigSet(configSetId, newConfigSetName)
local configSet = self.configSets[configSetId]
local newConfigSet = copyTable(configSet)
newConfigSet.id = #self.configSets + 1
newConfigSet.title = newConfigSetName or configSet.title .. " (Copy)"
t_insert(self.configSets, newConfigSet)
return newConfigSet
end

-- Changes the active config set
function ConfigTabClass:SetActiveConfigSet(configSetId, init)
function ConfigTabClass:SetActiveConfigSet(configSetId, init, deferSync)
-- Initialize config sets if needed
if not self.configSetOrderList[1] then
self.configSetOrderList[1] = 1
Expand All @@ -1002,5 +1009,7 @@ function ConfigTabClass:SetActiveConfigSet(configSetId, init)
self:BuildModList()
end
self.build.buildFlag = true
self.build:SyncLoadouts()
if not deferSync then
self.build:SyncLoadouts()
end
end
7 changes: 1 addition & 6 deletions src/Classes/ItemSetListControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@ local ItemSetListClass = newClass("ItemSetListControl", "ListControl", function(
self.ListControl(anchor, rect, 16, "VERTICAL", true, itemsTab.itemSetOrderList)
self.itemsTab = itemsTab
self.controls.copy = new("ButtonControl", {"BOTTOMLEFT",self,"TOP"}, {2, -4, 60, 18}, "Copy", function()
local newSet = copyTable(itemsTab.itemSets[self.selValue])
newSet.id = 1
while itemsTab.itemSets[newSet.id] do
newSet.id = newSet.id + 1
end
itemsTab.itemSets[newSet.id] = newSet
local newSet = itemsTab:CopyItemSet(self.selValue)
self:RenameSet(newSet, true)
end)
self.controls.copy.enabled = function()
Expand Down
14 changes: 12 additions & 2 deletions src/Classes/ItemsTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1351,8 +1351,16 @@ function ItemsTabClass:NewItemSet(itemSetId)
return itemSet
end

function ItemsTabClass:CopyItemSet(sourceItemSetId, newItemSetName)
local newSet = copyTable(self.itemSets[sourceItemSetId])
newSet.id = #self.itemSets + 1
newSet.title = newItemSetName or newSet.title .. " (Copy)"
self.itemSets[newSet.id] = newSet
return newSet
end

-- Changes the active item set
function ItemsTabClass:SetActiveItemSet(itemSetId)
function ItemsTabClass:SetActiveItemSet(itemSetId, deferSync)
local prevSet = self.activeItemSet
if not self.itemSets[itemSetId] then
itemSetId = self.itemSetOrderList[1]
Expand All @@ -1377,7 +1385,9 @@ function ItemsTabClass:SetActiveItemSet(itemSetId)
end
self.build.buildFlag = true
self:PopulateSlots()
self.build:SyncLoadouts()
if not deferSync then
self.build:SyncLoadouts()
end
end

-- Equips the given item in the given item set
Expand Down
10 changes: 3 additions & 7 deletions src/Classes/PassiveSpecListControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ local PassiveSpecListClass = newClass("PassiveSpecListControl", "ListControl", f
self.ListControl(anchor, rect, 16, "VERTICAL", true, treeTab.specList)
self.treeTab = treeTab
self.controls.copy = new("ButtonControl", {"BOTTOMLEFT",self,"TOP"}, {2, -4, 60, 18}, "Copy", function()
local newSpec = new("PassiveSpec", treeTab.build, self.selValue.treeVersion)
newSpec.title = self.selValue.title
newSpec.jewels = copyTable(self.selValue.jewels)
newSpec:RestoreUndoState(self.selValue:CreateUndoState())
newSpec:BuildClusterJewelGraphs()
local newSpec = treeTab:CopyTree(self.selValue)
self:RenameSpec(newSpec, "Copy Tree", true)
end)
self.controls.copy.enabled = function()
Expand Down Expand Up @@ -43,7 +39,7 @@ local PassiveSpecListClass = newClass("PassiveSpecListControl", "ListControl", f
self:UpdateItemsTabPassiveTreeDropdown()
end)

function PassiveSpecListClass:RenameSpec(spec, title, addOnName)
function PassiveSpecListClass:RenameSpec(spec, popupTitle, addOnName)
local controls = { }
controls.label = new("LabelControl", nil, {0, 20, 0, 16}, "^7Enter name for this passive tree:")
controls.edit = new("EditControl", nil, {0, 40, 350, 20}, spec.title, nil, nil, 100, function(buf)
Expand All @@ -66,7 +62,7 @@ function PassiveSpecListClass:RenameSpec(spec, title, addOnName)
main:ClosePopup()
end)
-- main:OpenPopup(370, 100, spec.title and "Rename" or "Set Name", controls, "save", "edit")
main:OpenPopup(370, 100, title, controls, "save", "edit")
main:OpenPopup(370, 100, popupTitle, controls, "save", "edit")
end

function PassiveSpecListClass:GetRowValue(column, index, spec)
Expand Down
Loading