Module:StormforgedController: Difference between revisions
From Against the Storm Official Wiki
(Added display override for inline links) |
(finished refactoring for list and inline display versions) |
||
(7 intermediate revisions by the same user not shown) | |||
Line 11: | Line 11: | ||
local AltarEffectsData = require("Module:AltarEffectsData") | local AltarEffectsData = require("Module:AltarEffectsData") | ||
local PerksData = require("Module:PerksData") | local PerksData = require("Module:PerksData") | ||
local ControllerUtilities = require("Module:ControllerUtilities") | |||
--endregion | --endregion | ||
Line 18: | Line 20: | ||
--region Private constants | --region Private constants | ||
local | local ARG_ID_LIST = "id" | ||
local ARG_NAME = "name" | local ARG_NAME = "name" | ||
local ARG_DESCRIPTION = "description" | local ARG_DESCRIPTION = "description" | ||
Line 25: | Line 27: | ||
local ARG_CAPTION = "caption" | local ARG_CAPTION = "caption" | ||
local ARG_SKIP_PRICES = "skip_prices" | local ARG_SKIP_PRICES = "skip_prices" | ||
local | local ARG_SKIP_FLAG_VALUE = "skip" | ||
local ARG_SHOW_ID = "show_id" | |||
local ARG_SHOW_DESCRIPTION = "show_description" | |||
local ARG_SHOW_REGULAR = "show_regular" | local ARG_SHOW_REGULAR = "show_regular" | ||
local | local ARG_SHOW_FLAG_VALUE = "show" | ||
local ARG_DISPLAY_OVERRIDE = "display" | local ARG_DISPLAY_OVERRIDE = "display" | ||
local ARG_DISPLAY_OVERRIDE_OPTION_LIST = "list" | local ARG_DISPLAY_OVERRIDE_OPTION_LIST = "list" | ||
Line 33: | Line 37: | ||
local ARG_LIST_TYPE = "list_type" | local ARG_LIST_TYPE = "list_type" | ||
local TEMPLATE_PARAMETER_CAPTION = ARG_CAPTION | |||
local TEMPLATE_PARAMETER_ID = ARG_ID_LIST | |||
local TEMPLATE_PARAMETER_CAPTION = | local TEMPLATE_PARAMETER_DESC = ARG_DESCRIPTION | ||
local TEMPLATE_PARAMETER_ID = | |||
local TEMPLATE_PARAMETER_DESC = | |||
local TEMPLATE_PARAMETER_PRICE_META = "price_in_meta_resources" | local TEMPLATE_PARAMETER_PRICE_META = "price_in_meta_resources" | ||
local TEMPLATE_PARAMETER_PRICE_VILLAGER = "price_in_villagers" | local TEMPLATE_PARAMETER_PRICE_VILLAGER = "price_in_villagers" | ||
local TEMPLATE_PARAMETER_UPGRADE_META = "price_for_upgrade_in_meta_resources" | local TEMPLATE_PARAMETER_UPGRADE_META = "price_for_upgrade_in_meta_resources" | ||
local TEMPLATE_PARAMETER_UPGRADE_VILLAGER = "price_for_upgrade_in_villagers" | local TEMPLATE_PARAMETER_UPGRADE_VILLAGER = "price_for_upgrade_in_villagers" | ||
local | local TEMPLATE_PARAMETER_SHOW_ID = ARG_SHOW_ID | ||
local TEMPLATE_PARAMETER_UPGRADE_FROM = "upgrades_from" | local TEMPLATE_PARAMETER_UPGRADE_FROM = "upgrades_from" | ||
local TEMPLATE_PARAMETER_LIST_TYPE = | local TEMPLATE_PARAMETER_LIST_TYPE = ARG_LIST_TYPE | ||
local TEMPLATE_PARAMETER_ICON_SIZE = "icon_size" | local TEMPLATE_PARAMETER_ICON_SIZE = "icon_size" | ||
local TEMPLATE_PARAMETER_ICON_SIZE_DEFAULT = "none" | local TEMPLATE_PARAMETER_ICON_SIZE_DEFAULT = "none" | ||
Line 55: | Line 56: | ||
local TEMPLATE_LIST_ITEM = "StormforgedCornerstonesList/item" | local TEMPLATE_LIST_ITEM = "StormforgedCornerstonesList/item" | ||
local TEMPLATE_INLINE_LINK = "pl" | local TEMPLATE_INLINE_LINK = "pl" | ||
--endregion | --endregion | ||
Line 65: | Line 64: | ||
local currentFrame = {} | local currentFrame = {} | ||
local altarIDs = {} | local altarIDs = {} | ||
local isIDAlreadyAdded = {} | local isIDAlreadyAdded = {} | ||
Line 73: | Line 73: | ||
--region Private methods | --region Private methods | ||
--- Runs through the list of perk IDs and checks that a name exists for each one. If not, it throws an error identifying the offending ID. | --- Runs through the list of perk IDs and checks that a name exists for each one. If not, it throws an error identifying the offending ID. | ||
Line 126: | Line 105: | ||
end | end | ||
--- Requests the lists of IDs from both AltarEffects and Perks data models, applies some post-processing, and stores them in the member variable. | --- Requests the desired lists of IDs from both AltarEffects and Perks data models, applies some post-processing, and stores them in the member variable altarIDs. | ||
--- | --- | ||
---@param | ---@param selectList table list of ids of the cornerstone to include | ||
---@param searchName string search term to look in cornerstone names | ---@param searchName string search term to look in cornerstone names | ||
---@param searchDesc string search term to look in cornerstone descriptions | ---@param searchDesc string search term to look in cornerstone descriptions | ||
---@param regularID string the id of the cornerstone that gets upgraded to a Stormforged version | ---@param regularID string the id of the cornerstone that gets upgraded to a Stormforged version | ||
---@param excludeList table list of ids | ---@param excludeList table list of ids | ||
local function loadIDs( | local function loadIDs(selectList, searchName, searchDesc, regularID, excludeList) | ||
altarIDs = {} | altarIDs = {} | ||
Line 139: | Line 118: | ||
local attemptedSearch = false | local attemptedSearch = false | ||
-- Load the selected | -- Load the selected IDs | ||
if | if selectList then | ||
loadStormforgedIDs( | loadStormforgedIDs(selectList, excludeList) | ||
attemptedSearch = true | -- It should always be true, but it can be blank. | ||
if #selectList > 0 then | |||
attemptedSearch = true | |||
end | |||
end | end | ||
Line 165: | Line 147: | ||
end | end | ||
-- Or, if no searching was even attempted (regardless of result), show them all | -- Or, if no searching was even attempted (regardless of result), show them all. | ||
if not attemptedSearch then | if not attemptedSearch then | ||
local newIDs = AltarEffectsData.getAllAltarIDs() | local newIDs = AltarEffectsData.getAllAltarIDs() | ||
Line 172: | Line 154: | ||
if #altarIDs > 0 then | if #altarIDs > 0 then | ||
-- Remove all IDs that aren't for Stormforged Cornerstones--there | -- Remove all IDs that aren't for Stormforged Cornerstones--there will be extra regular Perks pulled from PerksData whenever there are search terms. | ||
validateNamesFromIDs() | validateNamesFromIDs() | ||
--Alphabetize by name | -- Alphabetize by name. | ||
table.sort(altarIDs, compareNames) | table.sort(altarIDs, PerksData.compareNames) | ||
end | end | ||
end | end | ||
--- Ensures that if a caption is not defined, there is a suitable fallback in case the author has specified an id, name, or search term to use, so readers know what they're looking at. | --- Ensures that if a caption is not defined, there is a suitable fallback in case the author has specified an id, name, or search term to use, so readers know what they're looking at. | ||
Line 198: | Line 165: | ||
--- If no caption was specified and also none of those filtering parameters, then leave it up to the template by returning a blank caption. | --- If no caption was specified and also none of those filtering parameters, then leave it up to the template by returning a blank caption. | ||
--- | --- | ||
---@param | ---@param desiredCaption string the caption requested, if any | ||
---@param selectList table list of ids of the cornerstone to include | |||
---@param searchName string the second search parameter, a name | ---@param searchName string the second search parameter, a name | ||
---@param searchDesc string the third search parameter, a term in a description | ---@param searchDesc string the third search parameter, a term in a description | ||
---@param regularID string the id of the cornerstone that gets upgraded to a Stormforged version | ---@param regularID string the id of the cornerstone that gets upgraded to a Stormforged version | ||
---@return string an appropriate caption, or blank if it should be default | ---@return string an appropriate caption, or blank if it should be default | ||
local function resolveCaption( | local function resolveCaption(desiredCaption, selectList, searchName, searchDesc, regularID) | ||
-- No matter what, if the author provided a caption, use that. | |||
if desiredCaption and desiredCaption ~= "" then | if desiredCaption and desiredCaption ~= "" then | ||
return desiredCaption | return desiredCaption | ||
end | end | ||
-- If no selection, delegate to template. | |||
local addedToText = false | |||
desiredCaption = "" .. #altarIDs .. " Stormforged Cornerstones" | |||
if selectList and #selectList > 0 then | |||
if #selectList == 1 then | |||
desiredCaption = desiredCaption .. " with ID '" .. selectList[1] .. "'" | |||
else | |||
desiredCaption = desiredCaption .. " with selected IDs" | |||
end | |||
addedToText = true | |||
end | end | ||
if searchName and searchName ~= "" then | |||
if addedToText then | |||
desiredCaption = desiredCaption .. " and" | |||
end | |||
desiredCaption = desiredCaption .. " named '" .. searchName .. "'" | |||
addedToText = true | |||
end | |||
if searchDesc and searchDesc ~= "" then | if searchDesc and searchDesc ~= "" then | ||
if addedToText then | |||
desiredCaption = desiredCaption .. " and" | |||
end | |||
desiredCaption = desiredCaption .. " mentioning '" .. searchDesc .. "'" | |||
addedToText = true | |||
end | end | ||
if | |||
if regularID and regularID ~= "" then | |||
if addedToText then | |||
desiredCaption = desiredCaption .. " and" | |||
end | |||
desiredCaption = desiredCaption .. " upgraded from '" .. regularID .. "'" | |||
addedToText = true | |||
end | end | ||
if | |||
if excludeList and #excludeList > 0 then | |||
desiredCaption = desiredCaption .. " (with exclusions)" | |||
addedToText = true | |||
end | end | ||
-- Delegate to the template for the default | if addedToText then | ||
return desiredCaption | |||
else | |||
-- Delegate to the template for the default | |||
return "" | |||
end | |||
end | end | ||
---resolveStartTemplate | ---resolveStartTemplate | ||
---@param | ---@param isSkippingPrices boolean true if skipping variant should be used | ||
---@return string the template name to use | ---@return string the template name to use | ||
local function resolveTableStartTemplate( | local function resolveTableStartTemplate(isSkippingPrices) | ||
local suffixIfSkipping = ( | local suffixIfSkipping = (isSkippingPrices and TEMPLATE_TABLE_SKIP_PRICES_VARIANT) or "" | ||
return TEMPLATE_TABLE_BASE .. suffixIfSkipping | return TEMPLATE_TABLE_BASE .. suffixIfSkipping | ||
Line 239: | Line 240: | ||
---resolveRowTemplate | ---resolveRowTemplate | ||
---@param | ---@param isSkippingPrices boolean true if skipping variant should be used | ||
---@return string the template name to use | ---@return string the template name to use | ||
local function resolveTableRowTemplate( | local function resolveTableRowTemplate(isSkippingPrices) | ||
local suffixIfSkipping = ( | local suffixIfSkipping = (isSkippingPrices and TEMPLATE_TABLE_SKIP_PRICES_VARIANT) or "" | ||
return TEMPLATE_TABLE_BASE .. TEMPLATE_TABLE_SUFFIX_ROW .. suffixIfSkipping | return TEMPLATE_TABLE_BASE .. TEMPLATE_TABLE_SUFFIX_ROW .. suffixIfSkipping | ||
Line 258: | Line 259: | ||
--- | --- | ||
---@param desiredCaption string the caption for the table, if any | ---@param desiredCaption string the caption for the table, if any | ||
---@param | ---@param isSkippingPrices boolean true if skipping variant should be used | ||
---@param | ---@param argsForTableTemplate table a set of arguments ready to pass through to the called template | ||
---@return string the wiki markup assembled by the view (other templates) | ---@return string the wiki markup assembled by the view (other templates) | ||
local function makeMarkupForTableStart(desiredCaption, | local function makeMarkupForTableStart(desiredCaption, isSkippingPrices, argsForTableTemplate) | ||
argsForTableTemplate[TEMPLATE_PARAMETER_CAPTION] = desiredCaption | |||
return currentFrame:expandTemplate{ title = resolveTableStartTemplate( | return currentFrame:expandTemplate{ title = resolveTableStartTemplate(isSkippingPrices), args = argsForTableTemplate } | ||
end | end | ||
Line 275: | Line 272: | ||
--- | --- | ||
---@param id string the unique identifier of a Stormforged Cornerstone to use to add data to a new table row | ---@param id string the unique identifier of a Stormforged Cornerstone to use to add data to a new table row | ||
---@param | ---@param isSkippingPrices boolean true if skipping variant should be used | ||
---@param | ---@param argsForTableTemplate table a set of arguments ready to pass through to the called template | ||
---@return string the wiki markup assembled by the view (other templates) | ---@return string the wiki markup assembled by the view (other templates) | ||
local function makeMarkupPerRow(id, | local function makeMarkupPerRow(id, isSkippingPrices, argsForTableTemplate) | ||
argsForTableTemplate[TEMPLATE_PARAMETER_ID] = id | |||
argsForTableTemplate[TEMPLATE_PARAMETER_DESC] = PerksData.getDescriptionByID(id) | |||
argsForTableTemplate[TEMPLATE_PARAMETER_UPGRADE_FROM] = AltarEffectsData.getRegularVersionEffectID(id) | |||
if | -- This is default, but adds a lot of extra template overhead if it's not needed, so only add it if necessary. | ||
if not isSkippingPrices then | |||
argsForTableTemplate[TEMPLATE_PARAMETER_PRICE_META] = AltarEffectsData.getPriceInMetaResources(id) | |||
argsForTableTemplate[TEMPLATE_PARAMETER_PRICE_VILLAGER] = AltarEffectsData.getPriceInVillagers(id) | |||
argsForTableTemplate[TEMPLATE_PARAMETER_UPGRADE_META] = AltarEffectsData.getUpgradePriceInMetaResources(id) | |||
argsForTableTemplate[TEMPLATE_PARAMETER_UPGRADE_VILLAGER] = AltarEffectsData.getUpgradePriceInVillagers(id) | |||
end | end | ||
return currentFrame:expandTemplate{ title = resolveTableRowTemplate( | return currentFrame:expandTemplate{ title = resolveTableRowTemplate(isSkippingPrices), args = argsForTableTemplate } | ||
end | end | ||
--- Handles assembling the rows for all of the IDs in the member variable list altarIDs. | --- Handles assembling the rows for all of the IDs in the member variable list altarIDs. | ||
--- | --- | ||
---@param | ---@param isSkippingPrices boolean true if skipping variant should be used | ||
---@param | ---@param argsForTableTemplate table a set of arguments ready to pass through to the called template | ||
---@return string the wiki markup assembled by the view (other templates) | ---@return string the wiki markup assembled by the view (other templates) | ||
local function makeMarkupForTableRows( | local function makeMarkupForTableRows(isSkippingPrices, argsForTableTemplate) | ||
local markup = "" | local markup = "" | ||
for _, id in ipairs(altarIDs) do | for _, id in ipairs(altarIDs) do | ||
markup = markup .. makeMarkupPerRow(id, | markup = markup .. makeMarkupPerRow(id, isSkippingPrices, argsForTableTemplate) | ||
end | end | ||
Line 328: | Line 320: | ||
--- Calls several methods to build pieces of the table's markup based on the author's requests. | --- Calls several methods to build pieces of the table's markup based on the author's requests. | ||
--- | --- | ||
---@param desiredCaption string override the table caption | ---@param desiredCaption string override the table caption | ||
---@param | ---@param isSkippingPrices boolean true if skipping variant should be used | ||
---@param | ---@param argsForTableTemplate table a set of arguments ready to pass through to the called template | ||
---@return string the wiki markup assembled by the view (other templates) | ---@return string the wiki markup assembled by the view (other templates) | ||
local function renderTable( | local function renderTable(desiredCaption, isSkippingPrices, argsForTableTemplate) | ||
local startMarkup = makeMarkupForTableStart(desiredCaption, isSkippingPrices, argsForTableTemplate) | |||
local rowsMarkup = makeMarkupForTableRows(isSkippingPrices, argsForTableTemplate) | |||
local startMarkup = makeMarkupForTableStart(desiredCaption, | |||
local rowsMarkup = makeMarkupForTableRows( | |||
return startMarkup .. rowsMarkup .. makeMarkupForTableEnd() | return startMarkup .. rowsMarkup .. makeMarkupForTableEnd() | ||
Line 355: | Line 335: | ||
---@param id string the id of the cornerstone to display | ---@param id string the id of the cornerstone to display | ||
---@param listType string the type of list to create | ---@param listType string the type of list to create | ||
---@param isShowingID boolean true when needing to show the ID column | |||
---@return string the wiki markup assembled by the view (other templates) | ---@return string the wiki markup assembled by the view (other templates) | ||
local function makeMarkupPerListItem(id, listType) | local function makeMarkupPerListItem(id, listType, isShowingID) | ||
local templateParameters = { | local templateParameters = { | ||
[TEMPLATE_PARAMETER_ID] = id, | [TEMPLATE_PARAMETER_ID] = id, | ||
[TEMPLATE_PARAMETER_LIST_TYPE] = listType | [TEMPLATE_PARAMETER_LIST_TYPE] = listType, | ||
[TEMPLATE_PARAMETER_SHOW_ID] = isShowingID and ARG_SHOW_FLAG_VALUE | |||
} | } | ||
Line 368: | Line 350: | ||
---makeMarkupForListItems | ---makeMarkupForListItems | ||
---@param listType string the type of list to create | ---@param listType string the type of list to create | ||
---@param isShowingID boolean true when needing to show the ID column | |||
---@return string the wiki markup assembled by the view (other templates) | ---@return string the wiki markup assembled by the view (other templates) | ||
local function makeMarkupForListItems(listType) | local function makeMarkupForListItems(listType, isShowingID) | ||
local markup = "" | local markup = "" | ||
for _, id in ipairs(altarIDs) do | for _, id in ipairs(altarIDs) do | ||
markup = markup .. makeMarkupPerListItem(id, listType) | markup = markup .. makeMarkupPerListItem(id, listType, isShowingID) | ||
end | end | ||
Line 380: | Line 363: | ||
---renderList | ---renderList | ||
---@param listType string the type of list to create | ---@param listType string the type of list to create | ||
---@param isShowingID boolean true when needing to show the ID column | |||
---@return string the wiki markup assembled by the view (other templates) | ---@return string the wiki markup assembled by the view (other templates) | ||
local function renderList( | local function renderList(listType, isShowingID) | ||
return makeMarkupForListItems(listType, isShowingID) | |||
return makeMarkupForListItems(listType) | |||
end | end | ||
---makeMarkupPerLink | ---makeMarkupPerLink | ||
---@param id string the id of the cornerstone to display | ---@param id string the id of the cornerstone to display | ||
---@param isShowingID boolean true when needing to show the ID column | |||
---@return string the wiki markup assembled by the view (other templates) | ---@return string the wiki markup assembled by the view (other templates) | ||
local function makeMarkupPerLink(id) | local function makeMarkupPerLink(id, isShowingID) | ||
local templateParameters = { | local templateParameters = { | ||
[TEMPLATE_PARAMETER_ID] = id, | [TEMPLATE_PARAMETER_ID] = id, | ||
[TEMPLATE_PARAMETER_ICON_SIZE] = TEMPLATE_PARAMETER_ICON_SIZE_DEFAULT | [TEMPLATE_PARAMETER_ICON_SIZE] = TEMPLATE_PARAMETER_ICON_SIZE_DEFAULT, | ||
} | } | ||
local link = currentFrame:expandTemplate{ title = TEMPLATE_INLINE_LINK, args = templateParameters } | |||
if isShowingID then | |||
return link .. " ('" .. id .. "')" | |||
else | |||
return link | |||
end | |||
end | end | ||
---makeMarkupForInlineLinks | ---makeMarkupForInlineLinks | ||
---@param isShowingID boolean true when needing to show the ID column | |||
---@return string the wiki markup assembled by the view (other templates) | ---@return string the wiki markup assembled by the view (other templates) | ||
local function makeMarkupForInlineLinks() | local function makeMarkupForInlineLinks(isShowingID) | ||
local markup = "" | local markup = "" | ||
Line 419: | Line 401: | ||
markup = markup .. ", " | markup = markup .. ", " | ||
end | end | ||
markup = markup .. makeMarkupPerLink(id) | markup = markup .. makeMarkupPerLink(id, isShowingID) | ||
end | end | ||
Line 426: | Line 408: | ||
---renderInline | ---renderInline | ||
---@param | ---@param isShowingID boolean true when needing to show the ID column | ||
---@return string the wiki markup assembled by the view (other templates) | ---@return string the wiki markup assembled by the view (other templates) | ||
local function renderInlineLinks( | local function renderInlineLinks(isShowingID) | ||
return makeMarkupForInlineLinks() | return makeMarkupForInlineLinks(isShowingID) | ||
end | end | ||
Line 454: | Line 427: | ||
-- Selection parameters | -- Selection parameters | ||
local | local selectList = ControllerUtilities.expandCommaSeparatedStringsIntoTable(frame.args[ARG_ID_LIST], false) | ||
local excludeList = ControllerUtilities.expandCommaSeparatedStringsIntoTable(frame.args[ARGS_EXCLUDE_LIST], true) | |||
local searchName = frame.args[ARG_NAME] | local searchName = frame.args[ARG_NAME] | ||
local searchDesc = frame.args[ARG_DESCRIPTION] | local searchDesc = frame.args[ARG_DESCRIPTION] | ||
local regularID = frame.args[ARG_UPGRADABLE_ID] | local regularID = frame.args[ARG_UPGRADABLE_ID] | ||
-- Display parameters | -- Display parameters | ||
local desiredCaption = frame.args[ARG_CAPTION] | |||
local displayOverride = frame.args[ARG_DISPLAY_OVERRIDE] | local displayOverride = frame.args[ARG_DISPLAY_OVERRIDE] | ||
local listType = frame.args[ARG_LIST_TYPE] | local listType = frame.args[ARG_LIST_TYPE] | ||
local isSkippingPrices = ARG_SKIP_FLAG_VALUE == frame.args[ARG_SKIP_PRICES] | |||
local isShowingID = ARG_SHOW_FLAG_VALUE == frame.args[ARG_SHOW_ID] | |||
local | -- For clarity, copy each value instead of reusing the whole args table. | ||
local argumentsToPassThroughToTable = { | |||
[ARG_SKIP_PRICES] = frame.args[ARG_SKIP_PRICES], | |||
[ARG_SHOW_ID] = frame.args[ARG_SHOW_ID], | |||
[ARG_SHOW_DESCRIPTION] = frame.args[ARG_SHOW_DESCRIPTION], | |||
[ARG_SHOW_REGULAR] = frame.args[ARG_SHOW_REGULAR] | |||
} | |||
currentFrame = frame | currentFrame = frame | ||
loadIDs(selectList, searchName, searchDesc, regularID, excludeList) | |||
if #altarIDs < 1 then | |||
return "No matching Stormforged Cornerstones found." | |||
end | |||
if displayOverride == ARG_DISPLAY_OVERRIDE_OPTION_LIST then | if displayOverride == ARG_DISPLAY_OVERRIDE_OPTION_LIST then | ||
return renderList( | return renderList(listType, isShowingID) | ||
end | end | ||
if displayOverride == ARG_DISPLAY_OVERRIDE_OPTION_INLINE then | if displayOverride == ARG_DISPLAY_OVERRIDE_OPTION_INLINE then | ||
return renderInlineLinks( | return renderInlineLinks(isShowingID) | ||
end | end | ||
-- Default display is table. | |||
desiredCaption = resolveCaption(desiredCaption, selectList, searchName, searchDesc, regularID) | |||
return renderTable(desiredCaption, isSkippingPrices, argumentsToPassThroughToTable) | |||
end | end | ||
Latest revision as of 03:38, 5 May 2024
Documentation for this module may be created at Module:StormforgedController/doc
--- --- Serves the Stormforged Cornerstones template by capturing input and using it to control the display of data. --- ---@module StormforgedController local StormforgedController = {} --region Dependencies local AltarEffectsData = require("Module:AltarEffectsData") local PerksData = require("Module:PerksData") local ControllerUtilities = require("Module:ControllerUtilities") --endregion --region Private constants local ARG_ID_LIST = "id" local ARG_NAME = "name" local ARG_DESCRIPTION = "description" local ARG_UPGRADABLE_ID = "upgrades_from_id" local ARGS_EXCLUDE_LIST = "exclude" local ARG_CAPTION = "caption" local ARG_SKIP_PRICES = "skip_prices" local ARG_SKIP_FLAG_VALUE = "skip" local ARG_SHOW_ID = "show_id" local ARG_SHOW_DESCRIPTION = "show_description" local ARG_SHOW_REGULAR = "show_regular" local ARG_SHOW_FLAG_VALUE = "show" local ARG_DISPLAY_OVERRIDE = "display" local ARG_DISPLAY_OVERRIDE_OPTION_LIST = "list" local ARG_DISPLAY_OVERRIDE_OPTION_INLINE = "inline" local ARG_LIST_TYPE = "list_type" local TEMPLATE_PARAMETER_CAPTION = ARG_CAPTION local TEMPLATE_PARAMETER_ID = ARG_ID_LIST local TEMPLATE_PARAMETER_DESC = ARG_DESCRIPTION local TEMPLATE_PARAMETER_PRICE_META = "price_in_meta_resources" local TEMPLATE_PARAMETER_PRICE_VILLAGER = "price_in_villagers" local TEMPLATE_PARAMETER_UPGRADE_META = "price_for_upgrade_in_meta_resources" local TEMPLATE_PARAMETER_UPGRADE_VILLAGER = "price_for_upgrade_in_villagers" local TEMPLATE_PARAMETER_SHOW_ID = ARG_SHOW_ID local TEMPLATE_PARAMETER_UPGRADE_FROM = "upgrades_from" local TEMPLATE_PARAMETER_LIST_TYPE = ARG_LIST_TYPE local TEMPLATE_PARAMETER_ICON_SIZE = "icon_size" local TEMPLATE_PARAMETER_ICON_SIZE_DEFAULT = "none" local TEMPLATE_TABLE_BASE = "StormforgedCornerstonesTable" local TEMPLATE_TABLE_SUFFIX_ROW = "/row" local TEMPLATE_TABLE_SUFFIX_END = "/end" local TEMPLATE_TABLE_SKIP_PRICES_VARIANT = "/SkipPrices" local TEMPLATE_LIST_ITEM = "StormforgedCornerstonesList/item" local TEMPLATE_INLINE_LINK = "pl" --endregion --region Private member variables local currentFrame = {} local altarIDs = {} local isIDAlreadyAdded = {} --endregion --region Private methods --- Runs through the list of perk IDs and checks that a name exists for each one. If not, it throws an error identifying the offending ID. --- --- Works from the member variable altarIDs --- local function validateNamesFromIDs() for _, id in ipairs(altarIDs) do --Validate the names. This should never happen, but this is here to save hours of troubleshooting. local name = PerksData.getNameByID(id) if not name then error(ERROR_PREFIX_NAME_NOT_FOUND .. "id=" .. id) end end end --- Takes a list of possible IDs and only loads the valid ones (Stormforged ones) to the member variable altarIDs. Skips all ids present in the exclude list. --- ---@param newIDs table a list of possible IDs to add to main list ---@param excludeList table where keys are ids to skip and the values are `true` local function loadStormforgedIDs(newIDs, excludeList) for _, id in ipairs(newIDs) do if AltarEffectsData.isIDValid(id) and not excludeList[id] and not isIDAlreadyAdded[id] then table.insert(altarIDs, id) isIDAlreadyAdded[id] = true end end end --- Requests the desired lists of IDs from both AltarEffects and Perks data models, applies some post-processing, and stores them in the member variable altarIDs. --- ---@param selectList table list of ids of the cornerstone to include ---@param searchName string search term to look in cornerstone names ---@param searchDesc string search term to look in cornerstone descriptions ---@param regularID string the id of the cornerstone that gets upgraded to a Stormforged version ---@param excludeList table list of ids local function loadIDs(selectList, searchName, searchDesc, regularID, excludeList) altarIDs = {} isIDAlreadyAdded = {} local attemptedSearch = false -- Load the selected IDs if selectList then loadStormforgedIDs(selectList, excludeList) -- It should always be true, but it can be blank. if #selectList > 0 then attemptedSearch = true end end -- Add any name matches if searchName and searchName ~= "" then local newIDs = PerksData.getAllPerkIDsWhereName(searchName) loadStormforgedIDs(newIDs, excludeList) attemptedSearch = true end -- Add any description matches if searchDesc and searchDesc ~= "" then local newIDs = PerksData.getAllPerkIDsWhereDescription(searchDesc) loadStormforgedIDs(newIDs, excludeList) attemptedSearch = true end -- Add any upgrade matches if regularID and regularID ~= "" then loadStormforgedIDs({ AltarEffectsData.getUpgradeWhereRegularID(regularID) }, excludeList) attemptedSearch = true end -- Or, if no searching was even attempted (regardless of result), show them all. if not attemptedSearch then local newIDs = AltarEffectsData.getAllAltarIDs() loadStormforgedIDs(newIDs, excludeList) end if #altarIDs > 0 then -- Remove all IDs that aren't for Stormforged Cornerstones--there will be extra regular Perks pulled from PerksData whenever there are search terms. validateNamesFromIDs() -- Alphabetize by name. table.sort(altarIDs, PerksData.compareNames) end end --- Ensures that if a caption is not defined, there is a suitable fallback in case the author has specified an id, name, or search term to use, so readers know what they're looking at. --- --- If no caption was specified and also none of those filtering parameters, then leave it up to the template by returning a blank caption. --- ---@param desiredCaption string the caption requested, if any ---@param selectList table list of ids of the cornerstone to include ---@param searchName string the second search parameter, a name ---@param searchDesc string the third search parameter, a term in a description ---@param regularID string the id of the cornerstone that gets upgraded to a Stormforged version ---@return string an appropriate caption, or blank if it should be default local function resolveCaption(desiredCaption, selectList, searchName, searchDesc, regularID) -- No matter what, if the author provided a caption, use that. if desiredCaption and desiredCaption ~= "" then return desiredCaption end -- If no selection, delegate to template. local addedToText = false desiredCaption = "" .. #altarIDs .. " Stormforged Cornerstones" if selectList and #selectList > 0 then if #selectList == 1 then desiredCaption = desiredCaption .. " with ID '" .. selectList[1] .. "'" else desiredCaption = desiredCaption .. " with selected IDs" end addedToText = true end if searchName and searchName ~= "" then if addedToText then desiredCaption = desiredCaption .. " and" end desiredCaption = desiredCaption .. " named '" .. searchName .. "'" addedToText = true end if searchDesc and searchDesc ~= "" then if addedToText then desiredCaption = desiredCaption .. " and" end desiredCaption = desiredCaption .. " mentioning '" .. searchDesc .. "'" addedToText = true end if regularID and regularID ~= "" then if addedToText then desiredCaption = desiredCaption .. " and" end desiredCaption = desiredCaption .. " upgraded from '" .. regularID .. "'" addedToText = true end if excludeList and #excludeList > 0 then desiredCaption = desiredCaption .. " (with exclusions)" addedToText = true end if addedToText then return desiredCaption else -- Delegate to the template for the default return "" end end ---resolveStartTemplate ---@param isSkippingPrices boolean true if skipping variant should be used ---@return string the template name to use local function resolveTableStartTemplate(isSkippingPrices) local suffixIfSkipping = (isSkippingPrices and TEMPLATE_TABLE_SKIP_PRICES_VARIANT) or "" return TEMPLATE_TABLE_BASE .. suffixIfSkipping end ---resolveRowTemplate ---@param isSkippingPrices boolean true if skipping variant should be used ---@return string the template name to use local function resolveTableRowTemplate(isSkippingPrices) local suffixIfSkipping = (isSkippingPrices and TEMPLATE_TABLE_SKIP_PRICES_VARIANT) or "" return TEMPLATE_TABLE_BASE .. TEMPLATE_TABLE_SUFFIX_ROW .. suffixIfSkipping end ---resolveEndTemplate ---@return string the template name to use local function resolveTableEndTemplate() return TEMPLATE_TABLE_BASE .. TEMPLATE_TABLE_SUFFIX_END end --- Calls the view (other templates) to render the beginning of the table. --- ---@param desiredCaption string the caption for the table, if any ---@param isSkippingPrices boolean true if skipping variant should be used ---@param argsForTableTemplate table a set of arguments ready to pass through to the called template ---@return string the wiki markup assembled by the view (other templates) local function makeMarkupForTableStart(desiredCaption, isSkippingPrices, argsForTableTemplate) argsForTableTemplate[TEMPLATE_PARAMETER_CAPTION] = desiredCaption return currentFrame:expandTemplate{ title = resolveTableStartTemplate(isSkippingPrices), args = argsForTableTemplate } end --- Calls the view (other templates) to render a single row of the table with data based on the provided identifier. --- ---@param id string the unique identifier of a Stormforged Cornerstone to use to add data to a new table row ---@param isSkippingPrices boolean true if skipping variant should be used ---@param argsForTableTemplate table a set of arguments ready to pass through to the called template ---@return string the wiki markup assembled by the view (other templates) local function makeMarkupPerRow(id, isSkippingPrices, argsForTableTemplate) argsForTableTemplate[TEMPLATE_PARAMETER_ID] = id argsForTableTemplate[TEMPLATE_PARAMETER_DESC] = PerksData.getDescriptionByID(id) argsForTableTemplate[TEMPLATE_PARAMETER_UPGRADE_FROM] = AltarEffectsData.getRegularVersionEffectID(id) -- This is default, but adds a lot of extra template overhead if it's not needed, so only add it if necessary. if not isSkippingPrices then argsForTableTemplate[TEMPLATE_PARAMETER_PRICE_META] = AltarEffectsData.getPriceInMetaResources(id) argsForTableTemplate[TEMPLATE_PARAMETER_PRICE_VILLAGER] = AltarEffectsData.getPriceInVillagers(id) argsForTableTemplate[TEMPLATE_PARAMETER_UPGRADE_META] = AltarEffectsData.getUpgradePriceInMetaResources(id) argsForTableTemplate[TEMPLATE_PARAMETER_UPGRADE_VILLAGER] = AltarEffectsData.getUpgradePriceInVillagers(id) end return currentFrame:expandTemplate{ title = resolveTableRowTemplate(isSkippingPrices), args = argsForTableTemplate } end --- Handles assembling the rows for all of the IDs in the member variable list altarIDs. --- ---@param isSkippingPrices boolean true if skipping variant should be used ---@param argsForTableTemplate table a set of arguments ready to pass through to the called template ---@return string the wiki markup assembled by the view (other templates) local function makeMarkupForTableRows(isSkippingPrices, argsForTableTemplate) local markup = "" for _, id in ipairs(altarIDs) do markup = markup .. makeMarkupPerRow(id, isSkippingPrices, argsForTableTemplate) end return markup end --- Calls the view (other templates) to render the end of the table. --- ---@return string the wiki markup assembled by the view (other templates) local function makeMarkupForTableEnd() return currentFrame:expandTemplate{ title = resolveTableEndTemplate(), args = {} } end ---Calls the view (other templates) to render the content and appends it to the wiki markup string that will replace this controller's template. --- --- Calls several methods to build pieces of the table's markup based on the author's requests. --- ---@param desiredCaption string override the table caption ---@param isSkippingPrices boolean true if skipping variant should be used ---@param argsForTableTemplate table a set of arguments ready to pass through to the called template ---@return string the wiki markup assembled by the view (other templates) local function renderTable(desiredCaption, isSkippingPrices, argsForTableTemplate) local startMarkup = makeMarkupForTableStart(desiredCaption, isSkippingPrices, argsForTableTemplate) local rowsMarkup = makeMarkupForTableRows(isSkippingPrices, argsForTableTemplate) return startMarkup .. rowsMarkup .. makeMarkupForTableEnd() end ---makeMarkupPerListITem ---@param id string the id of the cornerstone to display ---@param listType string the type of list to create ---@param isShowingID boolean true when needing to show the ID column ---@return string the wiki markup assembled by the view (other templates) local function makeMarkupPerListItem(id, listType, isShowingID) local templateParameters = { [TEMPLATE_PARAMETER_ID] = id, [TEMPLATE_PARAMETER_LIST_TYPE] = listType, [TEMPLATE_PARAMETER_SHOW_ID] = isShowingID and ARG_SHOW_FLAG_VALUE } return currentFrame:expandTemplate{ title = TEMPLATE_LIST_ITEM, args = templateParameters } end ---makeMarkupForListItems ---@param listType string the type of list to create ---@param isShowingID boolean true when needing to show the ID column ---@return string the wiki markup assembled by the view (other templates) local function makeMarkupForListItems(listType, isShowingID) local markup = "" for _, id in ipairs(altarIDs) do markup = markup .. makeMarkupPerListItem(id, listType, isShowingID) end return markup end ---renderList ---@param listType string the type of list to create ---@param isShowingID boolean true when needing to show the ID column ---@return string the wiki markup assembled by the view (other templates) local function renderList(listType, isShowingID) return makeMarkupForListItems(listType, isShowingID) end ---makeMarkupPerLink ---@param id string the id of the cornerstone to display ---@param isShowingID boolean true when needing to show the ID column ---@return string the wiki markup assembled by the view (other templates) local function makeMarkupPerLink(id, isShowingID) local templateParameters = { [TEMPLATE_PARAMETER_ID] = id, [TEMPLATE_PARAMETER_ICON_SIZE] = TEMPLATE_PARAMETER_ICON_SIZE_DEFAULT, } local link = currentFrame:expandTemplate{ title = TEMPLATE_INLINE_LINK, args = templateParameters } if isShowingID then return link .. " ('" .. id .. "')" else return link end end ---makeMarkupForInlineLinks ---@param isShowingID boolean true when needing to show the ID column ---@return string the wiki markup assembled by the view (other templates) local function makeMarkupForInlineLinks(isShowingID) local markup = "" for i, id in ipairs(altarIDs) do if i > 1 then markup = markup .. ", " end markup = markup .. makeMarkupPerLink(id, isShowingID) end return markup end ---renderInline ---@param isShowingID boolean true when needing to show the ID column ---@return string the wiki markup assembled by the view (other templates) local function renderInlineLinks(isShowingID) return makeMarkupForInlineLinks(isShowingID) end --endregion --region Public methods ---main ---@param frame table the MediaWiki frame provided by the template call ---@return string wiki markup to display function StormforgedController.main(frame) -- Selection parameters local selectList = ControllerUtilities.expandCommaSeparatedStringsIntoTable(frame.args[ARG_ID_LIST], false) local excludeList = ControllerUtilities.expandCommaSeparatedStringsIntoTable(frame.args[ARGS_EXCLUDE_LIST], true) local searchName = frame.args[ARG_NAME] local searchDesc = frame.args[ARG_DESCRIPTION] local regularID = frame.args[ARG_UPGRADABLE_ID] -- Display parameters local desiredCaption = frame.args[ARG_CAPTION] local displayOverride = frame.args[ARG_DISPLAY_OVERRIDE] local listType = frame.args[ARG_LIST_TYPE] local isSkippingPrices = ARG_SKIP_FLAG_VALUE == frame.args[ARG_SKIP_PRICES] local isShowingID = ARG_SHOW_FLAG_VALUE == frame.args[ARG_SHOW_ID] -- For clarity, copy each value instead of reusing the whole args table. local argumentsToPassThroughToTable = { [ARG_SKIP_PRICES] = frame.args[ARG_SKIP_PRICES], [ARG_SHOW_ID] = frame.args[ARG_SHOW_ID], [ARG_SHOW_DESCRIPTION] = frame.args[ARG_SHOW_DESCRIPTION], [ARG_SHOW_REGULAR] = frame.args[ARG_SHOW_REGULAR] } currentFrame = frame loadIDs(selectList, searchName, searchDesc, regularID, excludeList) if #altarIDs < 1 then return "No matching Stormforged Cornerstones found." end if displayOverride == ARG_DISPLAY_OVERRIDE_OPTION_LIST then return renderList(listType, isShowingID) end if displayOverride == ARG_DISPLAY_OVERRIDE_OPTION_INLINE then return renderInlineLinks(isShowingID) end -- Default display is table. desiredCaption = resolveCaption(desiredCaption, selectList, searchName, searchDesc, regularID) return renderTable(desiredCaption, isSkippingPrices, argumentsToPassThroughToTable) end --endregion return StormforgedController