Module:PerkSearchController
From Against the Storm Official Wiki
Documentation for this module may be created at Module:PerkSearchController/doc
---
--- Module for searching data on perks and displaying results
---
--- @module PerkSearchController
local PerkSearchController = {}
local PerkSearchResultsView = require("Module:PerkSearchResultsView")
local PerksData = require("Module:PerksData")
--region Private member variables
--endregion
--region Private constants
--endregion
--region Private methods
---
--- Takes two lists and returns the intersection of the two. Slightly more
--- efficient if the second list is smaller than the first.
---
---@param list1 table a flat table (list of values)
---@param list2 table another flat table
---@return table a similarly flat table consisting only of the values that are in both provided lists
local function findIntersection(list1, list2)
local intersection = {}
-- Create a new mapping to efficiently check for existence in list2 by
-- checking the same ID in the next loop.
local setList2 = {}
for _, value in ipairs(list2 or {}) do
setList2[value] = true
end
-- Check for intersection and populate the result table.
for _, valueToFind in ipairs(list1 or {}) do
if setList2[valueToFind] then
table.insert(intersection, valueToFind)
end
end
if #intersection == 0 then
return nil
end
return intersection
end
---
--- Takes two lists and returns the union of the two.
---
---@param list1 table a flat table (list of values)
---@param list2 table another flat table
---@return table a similarly flat table consisting of the values of both lists
local function findUnion(list1, list2)
local union = {}
for _, value in ipairs(list2) do
table.insert(union, value)
end
-- Have to check before adding them to not add duplicates.
for _, value in ipairs(list1) do
for _, alreadyValue in ipairs(list2) do
if value ~= alreadyValue then
table.insert(union, value)
end
end
end
return union
end
---
--- Runs through the provided list of IDs and returns true if any are from
--- a Trader.
---
---@param perkIDsList table list of perkIDs
---@return boolean whether any in the list are from a Trader
local function isAnyFromTrader(perkIDsList)
-- Should never be nil at runtime.
if not perkIDsList then
error("Invalid list of perk IDs.")
end
for _, perkID in ipairs(perkIDsList) do
if PerksData.isFromTraderByID(perkID) then
return true
end
end
return false
end
---
--- Searches through perks for matches in descriptions and names and returns
--- the results of both merged into one list.
---
---@param searchTerm string the terms to search for
---@return table a list of perk IDs that match
local function searchAllNamesAndDescriptions(searchTerm)
local listFromSearchingNames = PerksData.getAllPerkIDsWhereName(searchTerm)
local listFromSearchingDescriptions = PerksData.getAllPerkIDsWhereDescription(searchTerm)
return findUnion(listFromSearchingDescriptions, listFromSearchingNames)
end
local function buildRowsForPerks(perkList, displayOverride)
for _, perkID in ipairs(perkList or {}) do
local perkName = PerksData.getNameByID(perkID)
local description = PerksData.getDescriptionByID(perkID)
local iconFilename = PerksData.getIconByID(perkID)
local rarity = PerksData.getRarityByID(perkID)
local price = PerksData.getPriceByID(perkID)
local sourceCornerstone = PerksData.isFromCornerstoneByID(perkID)
local sourceEvent = PerksData.isFromEventByID(perkID)
local sourceOrder = PerksData.isFromOrderByID(perkID)
local sourceTrader = PerksData.isFromTraderByID(perkID)
PerkSearchResultsView.addRowForPerk(displayOverride, perkName,
description, iconFilename, rarity, price,
sourceCornerstone, sourceEvent, sourceOrder, sourceTrader)
end
end
local function filterAllSources(listOfIDs, source)
-- Remove any that do not have the specified source.
for i, perkID in pairs(listOfIDs) do
if not PerksData.isAnySource(perkID, source) then
listOfIDs[i] = nil
end
end
end
local function filterAllRarities(listOfIDs, rarity)
-- Remove any that do not have the specified rarity.
for i, perkID in pairs(listOfIDs) do
if not PerksData.isRarityMatchByID(perkID, rarity) then
listOfIDs[i] = nil
end
end
end
function PerkSearchController.renderFromID(perkID, displayOverride)
local perkName = PerksData.getNameByID(perkID)
if not perkName then
return "No perk found with ID " .. perkID .. "."
end
local isFromTrader = PerksData.isFromTraderByID(perkID)
PerkSearchResultsView.startViewForPerk(perkName, displayOverride, isFromTrader)
buildRowsForPerks( { perkID }, displayOverride )
return PerkSearchResultsView.endView(displayOverride)
end
function PerkSearchController.renderFromName(name, displayOverride)
local perkIDsList = PerksData.getAllPerkIDsByName(name)
if not perkIDsList or #perkIDsList == 0 then
return "No perk found with name " .. name .. "."
end
local numPerks = #perkIDsList
local isFromTrader = isAnyFromTrader(perkIDsList)
PerkSearchResultsView.startViewForName(name, displayOverride, numPerks, isFromTrader)
buildRowsForPerks(perkIDsList, displayOverride)
return PerkSearchResultsView.endView(displayOverride)
end
function PerkSearchController.renderSearch(searchTerm, source, rarity, displayOverride)
local starterList = searchAllNamesAndDescriptions(searchTerm)
local filteredList = starterList
if source ~= nil then
filteredList = filterAllSources(filteredList, source)
end
if rarity ~= nil then
filteredList = filterAllRarities(filteredList, rarity)
end
if not filteredList or #filteredList == 0 then
return "No perk found with specified search criteria."
end
local numPerks = #perkIDsList
local isFromTrader = isAnyFromTrader(perkIDsList)
PerkSearchResultsView.startViewForSearchResults(searchTerm, source, rarity, displayOverride, numPerks, isFromTrader)
buildRowsForPerks(filteredList, displayOverride)
return PerkSearchResultsView.endView(displayOverride)
end
--endregion
--region Public methods
function PerkSearchController.searchResults(frame)
-- Extract the template parameters.
local perkID = frame.args.id or frame.args[1]
local name = frame.args.name
local searchTerm = frame.args.search
local source = frame.args.source
local rarity = frame.args.rarity
local displayOverride = frame.args.display
if id and id ~= "" then
return PerkSearchController.renderFromID(perkID, displayOverride)
else
if name and name ~= "" then
return PerkSearchController.renderFromName(name, displayOverride)
else
if searchTerm and searchTerm ~= "" then
return PerkSearchController.renderSearch(searchTerm, source, rarity, displayOverride)
else
return "Unknown parameter in Perk Search template."
end
end
end
end
--endregion
return PerkSearchController


