-- Path of Building
--
-- Class: Minion Search List
-- Minion list control with search field. Cannot be mutable.
--
local ipairs = ipairs
local t_insert = table.insert
local t_remove = table.remove
local s_format = string.format
local MinionSearchListClass = newClass("MinionSearchListControl", "MinionListControl", function(self, anchor, rect, data, list, dest, label)
self.MinionListControl(anchor, rect, data, list, dest, label)
self:sortSourceList()
self.unfilteredList = copyTable(list)
self.isMutable = false
self.controls.searchText = new("EditControl", {"BOTTOMLEFT",self,"TOPLEFT"}, {0, -2, 148, 18}, "", "Search", "%c", 100, function(buf)
self:ListFilterChanged(buf, self.controls.searchModeDropDown.selIndex)
self:sortSourceList()
end, nil, nil, true)
self.controls.searchModeDropDown = new("DropDownControl", {"LEFT",self.controls.searchText,"RIGHT"}, {2, 0, 60, 18}, { "Names", "Skills", "Both"}, function(index, value)
self:ListFilterChanged(self.controls.searchText.buf, index)
self:sortSourceList()
end)
self.controls.sortModeDropDown = new("DropDownControl", {"BOTTOMRIGHT", self.controls.searchModeDropDown, "TOPRIGHT"}, {0, -2, self.width, 18}, {
"Sort by Names",
"Sort by Life + ES",
"Sort by Life",
"Sort by Energy Shield",
"Sort by Attack Speed",
"Sort by Base Damage",
"Sort by Companion Reservation",
"Sort by Spectre Reservation",
"Sort by Fire Resistance",
"Sort by Cold Resistance",
"Sort by Lightning Resistance",
"Sort by Chaos Resistance",
"Sort by Total Resistance",
"Sort by Movement Speed",
}, function(index, value)
self:sortSourceList()
end)
self.labelPositionOffset = {0, -40}
if dest then
self.controls.add.y = self.controls.add.y - 40
else
self.controls.delete.y = self.controls.add.y - 40
end
end)
function MinionSearchListClass:DoesEntryMatchFilters(searchStr, minionId, filterMode)
if filterMode == 1 or filterMode == 3 then
local err, match = PCall(string.matchOrPattern, self.data.minions[minionId].name:lower(), searchStr)
if not err and match then
return true
end
end
if filterMode == 2 or filterMode == 3 then
for _, skillId in ipairs(self.data.minions[minionId].skillList) do
if self.data.skills[skillId] then
local err, match = PCall(string.matchOrPattern, self.data.skills[skillId].name:lower(), searchStr)
if not err and match then
return true
end
end
end
end
return false
end
function MinionSearchListClass:ListFilterChanged(buf, filterMode)
local searchStr = buf:lower():gsub("[%-%.%+%[%]%$%^%%%?%*]", "%%%0")
if searchStr:match("%S") then
local filteredList = { }
for _, minionId in pairs(self.unfilteredList) do
if self:DoesEntryMatchFilters(searchStr, minionId, filterMode) then
t_insert(filteredList, minionId)
end
end
self.list = filteredList
self:SelectIndex(1)
else
self.list = self.unfilteredList
end
end
function MinionSearchListClass:sortSourceList()
local sortFields = {
[1] = { field = "name", asc = true },
[2] = { field = "totalHitPoints", asc = false },
[3] = { field = "life", asc = false },
[4] = { field = "energyShield", asc = false },
[5] = { field = "attackTime", asc = true },
[6] = { field = "damage", asc = false },
[7] = { field = "companionReservation", asc = true },
[8] = { field = "spectreReservation", asc = true },
[9] = { field = "fireResist", asc = false },
[10] = { field = "coldResist", asc = false },
[11] = { field = "lightningResist", asc = false },
[12] = { field = "chaosResist", asc = false },
[13] = { field = "totalResist", asc = false },
[14] = { field = "baseMovementSpeed", asc = false },
}
local sortModeIndex = self.controls.sortModeDropDown and self.controls.sortModeDropDown.selIndex or 1
local sortOption = sortFields[sortModeIndex]
if sortOption then
table.sort(self.list, function(a, b)
local minionA = self.data.minions[a]
local minionB = self.data.minions[b]
local valueA = minionA[sortOption.field]
local valueB = minionB[sortOption.field]
if sortOption.field == "life" then
valueA = minionA.life * (1 - (minionA.energyShield or 0))
valueB = minionB.life * (1 - (minionB.energyShield or 0))
elseif sortOption.field == "totalHitPoints" then
valueA = minionA.life
valueB = minionB.life
elseif sortOption.field == "energyShield" then
valueA = (minionA.energyShield or 0) * minionA.life
valueB = (minionB.energyShield or 0) * minionB.life
elseif sortOption.field == "totalResist" then
valueA = (minionA.fireResist or 0) + (minionA.coldResist or 0) + (minionA.lightningResist or 0) + (minionA.chaosResist or 0)
valueB = (minionB.fireResist or 0) + (minionB.coldResist or 0) + (minionB.lightningResist or 0) + (minionB.chaosResist or 0)
end
if valueA == valueB then
return minionA.name < minionB.name
else
if sortOption.asc then
return valueA < valueB
else
return valueA > valueB
end
end
end)
end
end