Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions spec/System/TestLoadouts_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
describe("TestLoadouts", function()
before_each(function()
newBuild()

build.itemsTab:CreateDisplayItemFromRaw([[Dialla's Malefaction
Sage's Robe
Energy Shield: 95
EnergyShieldBasePercentile: 0
Variant: Pre 3.19.0
Variant: Current
Selected Variant: 2
Sage's Robe
Quality: 20
Sockets: R-G-B-B-B-B
LevelReq: 37
Implicits: 0
Gems can be Socketed in this Item ignoring Socket Colour
{variant:1}Gems Socketed in Red Sockets have +1 to Level
{variant:2}Gems Socketed in Red Sockets have +2 to Level
{variant:1}Gems Socketed in Green Sockets have +10% to Quality
{variant:2}Gems Socketed in Green Sockets have +30% to Quality
{variant:1}Gems Socketed in Blue Sockets gain 25% increased Experience
{variant:2}Gems Socketed in Blue Sockets gain 100% increased Experience
Has no Attribute Requirements]])
Comment on lines +6 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more of those pesky spaces here :)

build.itemsTab:AddDisplayItem()
runCallback("OnFrame")
end)

teardown(function()
-- newBuild() takes care of resetting everything in setup()
end)

local function getSelectedLoadout(treeId, itemIndex, itemId, skillIndex, skillId, configIndex, configId)
local selectedLoadout = {
treeId = treeId,
itemIndex = itemIndex,
itemId = itemId,
skillIndex = skillIndex,
skillId = skillId,
configIndex = configIndex,
configId = configId,
}
return selectedLoadout
end

describe("NewLoadout", function()
it("Creates a new loadout with the correct name", function()
build:NewLoadout("Loadout Name", function() end)
build:SyncLoadouts()
-- There are 5 static items in the list
assert.are.equals(7, #build.controls.buildLoadouts.list)
end)

it("calls the callback function", function()
local callbackCalled = false
build:NewLoadout("Loadout Name", function() callbackCalled = true end)
build:SyncLoadouts()
-- There are 5 static items in the list
assert.are.equals(7, #build.controls.buildLoadouts.list)
assert.are.equals(true, callbackCalled)
end)
end)

describe("CopyLoadout", function()
it("Copies a loadout with a new name", function()
local loadoutName = "Loadout Name"
local newSpec, newItemSet, newSkillSet, newConfigSet = build:CopyLoadout(1, 1, 1, 1, loadoutName)
build:SyncLoadouts()
-- There are 5 static items in the list
assert.are.equals(7, #build.controls.buildLoadouts.list)
-- First index is the "Loadout: " header, second index is the start of the loadouts
assert.is_not.same(build.controls.buildLoadouts.list[2], build.controls.buildLoadouts.list[3])
assert.are.equals(loadoutName, build.controls.buildLoadouts.list[3])
assert.is_not.same(newSpec, build.spec)
assert.is_not.same(newItemSet, build.itemsTab.itemSets[1])
assert.is_not.same(newSkillSet, build.skillsTab.skillSets[1])
assert.is_not.same(newConfigSet, build.configTab.configSets[1])
assert.is_same(loadoutName, newSpec.title)
assert.is_same(loadoutName, newItemSet.title)
assert.is_same(loadoutName, newSkillSet.title)
assert.is_same(loadoutName, newConfigSet.title)
end)
end)

describe("DeleteLoadout", function()
it("Deletes a loadout and sets the next to the requested loadout by name", function()
local loadoutNameToDelete = "Delete Me"
build:NewLoadout(loadoutNameToDelete, function() end)
build:SyncLoadouts()
-- There are 5 static items in the list
assert.are.equals(7, #build.controls.buildLoadouts.list)
local loadoutToDelete = build:GetLoadoutByName(loadoutNameToDelete)
local nextLoadout = build.controls.buildLoadouts.list[2] -- Default loadout

build:DeleteLoadout(loadoutNameToDelete, nextLoadout)
build:SyncLoadouts()

assert.is_nil(build.treeTab.specList[loadoutToDelete.specId])
assert.is_nil(build.skillsTab.skillSets[loadoutToDelete.skillSetId])
assert.is_nil(build.itemsTab.itemSets[loadoutToDelete.itemSetId])
assert.is_nil(build.configTab.configSets[loadoutToDelete.configSetId])

assert.is_nil(build.itemsTab.itemSetOrderList[loadoutToDelete.itemSetId])
assert.is_nil(build.skillsTab.skillSetOrderList[loadoutToDelete.skillSetId])
assert.is_nil(build.configTab.configSetOrderList[loadoutToDelete.configSetId])

assert.is_same(nextLoadout.specId, build.treeTab.displaySpecId)
assert.is_same(nextLoadout.itemSetId, build.itemsTab.displayItemSetId)
assert.is_same(nextLoadout.skillSetId, build.skillsTab.displaySkillSetId)
assert.is_same(nextLoadout.configSetId, build.configTab.displayConfigSetId)
end)
end)

describe("RenameLoadout", function()
it("renames a loadout and calls the callback", function()
local oldName = "Old Loadout"
local newName = "New Loadout"
local callbackCalled = false
build:NewLoadout(oldName, function() end)
build:SyncLoadouts()

build:RenameLoadout(oldName, newName, function() callbackCalled = true end)
build:SyncLoadouts()
-- Verify the new name appears in the loadout list
assert.is_same(newName, build.controls.buildLoadouts.list[3])
-- Verify titles updated on spec, itemSet, skillSet, and configSet
local loadout = build:GetLoadoutByName(newName)
assert.is_same(newName, build.treeTab.specList[loadout.specId].title)
assert.is_same(newName, build.itemsTab.itemSets[loadout.itemSetId].title)
assert.is_same(newName, build.skillsTab.skillSets[loadout.skillSetId].title)
assert.is_same(newName, build.configTab.configSets[loadout.configSetId].title)
-- Ensure callback was called
assert.is_true(callbackCalled)
-- Old name should no longer exist
assert.is_nil(build:GetLoadoutByName(oldName))
end)
end)
end)
151 changes: 151 additions & 0 deletions src/Classes/BuildSetListControl.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
-- Path of Building
--
-- Class: Build Set List
-- Build set list control.
--
local t_insert = table.insert
local t_remove = table.remove
local m_max = math.max
local s_format = string.format

local BuildSetListClass = newClass("BuildSetListControl", "ListControl", function(self, anchor, rect, buildMode, treeTab)
self.ListControl(anchor, rect, 16, "VERTICAL", true, buildMode.treeTab.specList)
self.buildMode = buildMode
self.controls.copy = new("ButtonControl", { "BOTTOMLEFT", self, "TOP" }, { 2, -4, 60, 18 }, "Copy", function()
local build = buildMode:GetLoadoutByName(self.selValue.title)
self:CopyLoadoutClick(build)
end)
self.controls.copy.enabled = function()
return self.selValue ~= nil
end
self.controls.delete = new("ButtonControl", { "LEFT", self.controls.copy, "RIGHT" }, { 4, 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.rename = new("ButtonControl", { "BOTTOMRIGHT", self, "TOP" }, { -2, -4, 60, 18 }, "Rename", function()
self:RenameLoadout(self.selValue)
end)
self.controls.rename.enabled = function()
return self.selValue ~= nil
end
self.controls.new = new("ButtonControl", { "RIGHT", self.controls.rename, "LEFT" }, { -4, 0, 60, 18 }, "New",
function()
self:NewLoadout()
end)
end)

function BuildSetListClass:RenameLoadout(spec, addOnName)
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.buildMode:RenameLoadout(specName, newTitle, function()
self.buildMode:SyncLoadouts()
self.buildMode.modFlag = true
end)
if addOnName then
self.selIndex = self.buildMode.treeTab.specListIdToOrderId[spec.id]
self.selValue = spec
end
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()
local newBuildName = controls.edit.buf
local newSpec = self.buildMode:CopyLoadout(build.specId, build.itemSetId, build.skillSetId, build.configSetId,
newBuildName)
self.buildMode:SyncLoadouts()
self.buildMode.modFlag = true
self.buildMode.controls.buildLoadouts:SetSel(newSpec.id + 1)
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: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.buildMode:NewLoadout(controls.edit.buf, function()
self.buildMode:SyncLoadouts()
self.buildMode.modFlag = true
self.buildMode.controls.buildLoadouts:SetSel(1)
main:ClosePopup()
end)
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()
t_remove(self.list, index)
local nextLoadoutIndex = index == self.buildMode.treeTab.activeSpec and m_max(1, index - 1) or index
local nextLoadout = self.list[nextLoadoutIndex]
self.buildMode:DeleteLoadout(spec.title or "Default", nextLoadout.title or "Default")
self.selIndex = nil
self.selValue = nil
end)
end
end

function BuildSetListClass:OnSelKeyDown(index, spec, key)
if key == "F2" then
self:RenameLoadout(spec)
end
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
Loading