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 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 unionList = {} -- Have to check before adding them to not add duplicates. local checkList = {} for _, value in ipairs(list2) do table.insert(unionList, value) checkList[value] = true end for _, value in ipairs(list1) do if not checkList[value] then table.insert(unionList, value) checkList[value] = true end end return unionList 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 --- --- Loops through a list of IDs and filters out any that don't match the --- specified source. --- ---@param listOfIDs table list of perk IDs ---@param source string the type of source to filter ---@return table the same list, but fewer items local function filterAllSources(listOfIDs, source) -- Should never be nil at runtime. if not source then error("Invalid parameter for source.") end local newList = {} -- Remove any that do not have the specified source. for _, perkID in ipairs(listOfIDs) do if PerksData.isAnySource(perkID, source) then table.insert(newList, perkID) end end return newList end --- --- Loops through a list of IDs and filters out any that don't match the --- specified rarity. --- ---@param listOfIDs table list of perk IDs ---@param rarity string a rarity constant to filter ---@return table the same list, but fewer items local function filterAllRarities(listOfIDs, rarity) -- Should never be nil at runtime. if not rarity then error("Invalid parameter for rarity.") end local newList = {} -- Remove any that do not have the specified rarity. for _, perkID in ipairs(listOfIDs) do if PerksData.isRarityMatchByID(perkID, rarity) then table.insert(newList, perkID) end end return newList end --- --- Main engine converting the list of IDs into calls to the View to render --- rows (or whatever based on list override). --- ---@param perkList table list of perk IDs ---@param displayOverride string how to display, if not default ---@param hasLastColumn boolean whether to write the last column local function buildRowsForPerks(perkList, displayOverride, hasLastColumn) 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, hasLastColumn) end end --- --- Organizes a list of IDs to send to the build method. Calls the View's --- setup, builds, and end. --- ---@param perkID string a single perk's ID ---@param displayOverride string how to display, if not default local function 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, isFromTrader) return PerkSearchResultsView.endView(displayOverride) end --- --- Organizes a list of IDs to send to the build method. Calls the View's --- setup, builds, and end. --- ---@param perkName string the name of a Perk ---@param displayOverride string how to display, if not default local function renderFromName(perkName, displayOverride) local perkIDsList = PerksData.getAllPerkIDsByName(perkName) if not perkIDsList or #perkIDsList == 0 then return "No perk found with name " .. perkName .. "." end local numPerks = #perkIDsList local isFromTrader = isAnyFromTrader(perkIDsList) PerkSearchResultsView.startViewForName(perkName, displayOverride, numPerks, isFromTrader) buildRowsForPerks(perkIDsList, displayOverride, isFromTrader) return PerkSearchResultsView.endView(displayOverride) end --- --- Organizes a list of IDs to send to the build method. Calls the View's --- setup, builds, and end. --- ---@param searchTerm string the text to search from all perks ---@param source string the type of source to filter, if any ---@param rarity string a rarity constant to filter, if any ---@param displayOverride string how to display, if not default ---@return table local function 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 = #filteredList local isFromTrader = isAnyFromTrader(filteredList) PerkSearchResultsView.startViewForSearchResults(searchTerm, source, rarity, displayOverride, numPerks, isFromTrader) buildRowsForPerks(filteredList, displayOverride, isFromTrader) return PerkSearchResultsView.endView(displayOverride) end --endregion --region Public methods --- --- Main method invoked from the template. --- ---@param frame table the MediaWiki calling context ---@return string long wiki markup with the results function PerkSearchController.search(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 -- Convert empty strings on these only to nil if source == "" then source = nil end if rarity == "" then rarity = nil end if perkID and perkID ~= "" then return renderFromID(perkID, displayOverride) else if name and name ~= "" then return renderFromName(name, displayOverride) else if searchTerm and searchTerm ~= "" then return renderSearch(searchTerm, source, rarity, displayOverride) else return "Unknown parameter in Perk Search template." end end end end --endregion return PerkSearchController