Module:PerkSearchController: Difference between revisions

From Against the Storm Official Wiki
(fixed the union method)
(changed filtering to make new list instead of edit parameter)
 
(3 intermediate revisions by the same user not shown)
Line 112: Line 112:
end
end


local newList = {}
-- Remove any that do not have the specified source.
-- Remove any that do not have the specified source.
for i, perkID in pairs(listOfIDs) do
for _, perkID in ipairs(listOfIDs) do


if not PerksData.isAnySource(perkID, source) then
if PerksData.isAnySource(perkID, source) then
listOfIDs[i] = nil
table.insert(newList, perkID)
end
end
end
end


return listOfIDs
return newList
end
end


Line 139: Line 140:
end
end


local newList = {}
-- Remove any that do not have the specified rarity.
-- Remove any that do not have the specified rarity.
for i, perkID in pairs(listOfIDs) do
for _, perkID in ipairs(listOfIDs) do


if not PerksData.isRarityMatchByID(perkID, rarity) then
if PerksData.isRarityMatchByID(perkID, rarity) then
listOfIDs[i] = nil
table.insert(newList, perkID)
end
end
end
end


return listOfIDs
return newList
end
end


Line 158: Line 160:
---@param perkList table list of perk IDs
---@param perkList table list of perk IDs
---@param displayOverride string how to display, if not default
---@param displayOverride string how to display, if not default
local function buildRowsForPerks(perkList, displayOverride)
---@param hasLastColumn boolean whether to write the last column
local function buildRowsForPerks(perkList, displayOverride, hasLastColumn)


for _, perkID in ipairs(perkList or {}) do
for _, perkID in ipairs(perkList or {}) do
Line 175: Line 178:
PerkSearchResultsView.addRowForPerk(displayOverride, perkName,
PerkSearchResultsView.addRowForPerk(displayOverride, perkName,
description, iconFilename, rarity, price,
description, iconFilename, rarity, price,
sourceCornerstone, sourceEvent, sourceOrder, sourceTrader)
sourceCornerstone, sourceEvent, sourceOrder, sourceTrader, hasLastColumn)
end
end
end
end
Line 199: Line 202:
PerkSearchResultsView.startViewForPerk(perkName, displayOverride, isFromTrader)
PerkSearchResultsView.startViewForPerk(perkName, displayOverride, isFromTrader)


buildRowsForPerks( { perkID }, displayOverride )
buildRowsForPerks( { perkID }, displayOverride, isFromTrader)


return PerkSearchResultsView.endView(displayOverride)
return PerkSearchResultsView.endView(displayOverride)
Line 225: Line 228:
PerkSearchResultsView.startViewForName(perkName, displayOverride, numPerks, isFromTrader)
PerkSearchResultsView.startViewForName(perkName, displayOverride, numPerks, isFromTrader)


buildRowsForPerks(perkIDsList, displayOverride)
buildRowsForPerks(perkIDsList, displayOverride, isFromTrader)


return PerkSearchResultsView.endView(displayOverride)
return PerkSearchResultsView.endView(displayOverride)
Line 257: Line 260:
end
end


local numPerks = #perkIDsList
local numPerks = #filteredList
local isFromTrader = isAnyFromTrader(perkIDsList)
local isFromTrader = isAnyFromTrader(filteredList)


PerkSearchResultsView.startViewForSearchResults(searchTerm, source, rarity, displayOverride, numPerks, isFromTrader)
PerkSearchResultsView.startViewForSearchResults(searchTerm, source, rarity, displayOverride, numPerks, isFromTrader)


buildRowsForPerks(filteredList, displayOverride)
buildRowsForPerks(filteredList, displayOverride, isFromTrader)


return PerkSearchResultsView.endView(displayOverride)
return PerkSearchResultsView.endView(displayOverride)
Line 287: Line 290:
local rarity = frame.args.rarity
local rarity = frame.args.rarity
local displayOverride = frame.args.display
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
if perkID and perkID ~= "" then

Latest revision as of 03:33, 4 December 2023

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