Module:Buildingbox: Difference between revisions
From Against the Storm Official Wiki
(Created to consolidate repetitive code for different buildings' infobox modules) |
(Updating to new secondary categories) |
||
(9 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
--- | --- Retrieves data for the specified building, resource, perk, etc. and sends the data over to the view, another template. | ||
--- | --- | ||
--- @module Buildingbox | --- @module Buildingbox | ||
Line 15: | Line 6: | ||
local | --region Dependencies | ||
local BuildingDataProxy = require("Module:BuildingDataProxy") | |||
local SpecializationsData = mw.loadData("Module:SpecializationsData") | |||
local SpeciesData = mw.loadData("Module:SpeciesData") | |||
local Construction = require("Module:Construction") | |||
local ControllerUtilities = require("Module:ControllerUtilities") | |||
local | local VIEW_TEMPLATE = "Buildingbox/view" | ||
local VIEW_TEMPLATE_SPECIALIZATION_LINK = "Specialization_link/view" | |||
local VIEW_TEMPLATE_SPECIES_LINK = "Species_link/view" | |||
local TEMPLATE_RECIPE = "Recipe" | |||
--endregion | |||
Line 29: | Line 26: | ||
--region Private constants | --region Private constants | ||
local | local ARG_NAME = "name" | ||
local PARAM_TITLE = "title" | |||
local PARAM_SUBTITLE = "subtitle" | |||
local PARAM_DESCRIPTION = "description" | |||
local PARAM_SPECIALIZATION = "specialization" | |||
local PARAM_ICON_FILENAME = "iconfilename" | |||
local PARAM_MOVABLE = "movable" | |||
local PARAM_WORKPLACES = "workplaces" | |||
local PARAM_STORAGE = "storage" | |||
local PARAM_RECIPES = "recipes" | |||
local PARAM_CONSTRUCTION_COST = "construction" | |||
local PARAM_CITY_SCORE = "cityscore" | |||
local PARAM_CONSTRUCTION_TIME = "constructiontime" | |||
local PARAM_CONSTRUCTION_SIZE = "constructionsize" | |||
local PARAM_ID = "id" | |||
--endregion | --endregion | ||
Line 42: | Line 49: | ||
--region Private methods | --region Private methods | ||
--- | ---renderSpecializations takes the ID of a building and looks up its specializations, calls external view templates to convert those specializations into usable content strings for display, and returns those strings concatenated together for display by the calling scope. | ||
--- | ---@param frame table the Mediawiki template calling context | ||
---@param id string the unique ID of the building | |||
---@param | ---@return string a content string ready for display | ||
---@return string | local function renderSpecializations(frame, id) | ||
local function | |||
local listOfSpecializationsAtBuilding = SpecializationsData.buildingSpecializations[id] | |||
if not listOfSpecializationsAtBuilding then | |||
return nil | |||
end | |||
local concatenatedStrings = "" | |||
for _, specializationIndex in ipairs(listOfSpecializationsAtBuilding) do | |||
-- | -- Specialization link first | ||
local specializationData = SpecializationsData.specializations[specializationIndex] | |||
local specializationString = frame:expandTemplate{ | |||
title = VIEW_TEMPLATE_SPECIALIZATION_LINK, | |||
args = { | |||
["iconfilename"] = specializationData[SpecializationsData.ICON_FILENAME], | |||
["name"] = specializationData[SpecializationsData.NAME], | |||
["type"] = specializationData[SpecializationsData.IS_COMFORTABLE] and "Comfort" or "Proficiency", | |||
["iconsize"] = "small", | |||
}, } | |||
-- Species link second, but just the icon | |||
local speciesID = specializationData[SpecializationsData.SPECIES] | |||
local speciesString = frame:expandTemplate{ | |||
title = VIEW_TEMPLATE_SPECIES_LINK, | |||
args = { | |||
["iconfilename"] = SpeciesData.species[speciesID][SpeciesData.ICON_FILENAME] .. ".png", | |||
["name"] = SpeciesData.species[speciesID][SpeciesData.NAME], | |||
["iconsize"] = "small", | |||
["display"] = "notext", | |||
}, } | |||
-- Separate multiple entries with line break | |||
if #concatenatedStrings > 1 then | |||
concatenatedStrings = concatenatedStrings .. "<br />" | |||
end | |||
concatenatedStrings = concatenatedStrings .. specializationString .. " " .. speciesString | |||
end | |||
if #concatenatedStrings < 1 then | |||
return "None" | |||
end | |||
return concatenatedStrings | |||
end | end | ||
---expandRecipeList | |||
---@param frame table | |||
---@param id table | |||
---@return table | |||
local function expandRecipeList(frame, id) | |||
local recipeMarkup = frame:expandTemplate{ | |||
title = TEMPLATE_RECIPE, | |||
args = { | |||
["building"] = BuildingDataProxy.getName(id), | |||
["display"] = "list", | |||
} | |||
} | |||
if recipeMarkup and not string.match(recipeMarkup, "^No recipes found") then | |||
return recipeMarkup | |||
else | |||
return "" | |||
end | |||
end | end | ||
---transformConstructionCosts | |||
---Gets the construction costs for the specified building and calls the utility function, not as a template, but directly, to build a table from that data directly. | |||
--- | --- | ||
---@return string markup for a table of construction goods to display | |||
local function transformConstructionCosts(id) | |||
---@ | |||
local function | |||
local constructionGoods = BuildingDataProxy.getConstructionCosts(id) | |||
if not constructionGoods then | |||
return nil | |||
end | |||
return "" .. Construction.makeTableFromData(constructionGoods) | |||
end | |||
---buildViewParameters | |||
---Populates a table of parameters for the view based on building data. | |||
--- | |||
---Leverages the building proxy to federate the query out to the right data model without worrying about which one it's coming from: | |||
--- getCategory | |||
--- getCityScore | |||
--- getConstructionCosts (as [goodName] = stack size) | |||
--- getConstructionTime | |||
--- getDescription | |||
--- getIcon | |||
--- isMovable | |||
--- getName | |||
--- getNumberOfWorkplaces | |||
--- getSize (as "X x Y") | |||
--- getStorage | |||
--- | |||
---@param frame table the Mediawiki template calling context | |||
---@param name string the name of the building | |||
---@return table of arguments for the view template | |||
local function buildViewParameters(frame, name) | |||
local id = BuildingDataProxy.getID(name) | |||
if not id then | |||
return nil | |||
end | |||
local viewParameters = {} | |||
viewParameters[PARAM_TITLE] = BuildingDataProxy.getName(id) | |||
viewParameters[PARAM_SUBTITLE] = BuildingDataProxy.getSecondCategory(id) .. "<br />" .. | |||
"(" .. BuildingDataProxy.getCategory(id) .. ")" | |||
viewParameters[PARAM_DESCRIPTION] = ControllerUtilities.findAndReplaceSpriteTagsWithFiles(BuildingDataProxy.getDescription(id), frame) | |||
viewParameters[PARAM_SPECIALIZATION] = renderSpecializations(frame, id) | |||
viewParameters[PARAM_ICON_FILENAME] = BuildingDataProxy.getIcon(id) | |||
viewParameters[PARAM_MOVABLE] = BuildingDataProxy.isMovable(id) and "true" | |||
viewParameters[PARAM_WORKPLACES] = BuildingDataProxy.getNumberOfWorkplaces(id) | |||
viewParameters[PARAM_RECIPES] = expandRecipeList(frame, id) | |||
viewParameters[PARAM_STORAGE] = BuildingDataProxy.getStorage(id) | |||
viewParameters[PARAM_CONSTRUCTION_COST] = transformConstructionCosts(id) | |||
viewParameters[PARAM_CITY_SCORE] = BuildingDataProxy.getCityScore(id) | |||
viewParameters[PARAM_CONSTRUCTION_TIME] = BuildingDataProxy.getConstructionTime(id) | |||
viewParameters[PARAM_CONSTRUCTION_SIZE] = BuildingDataProxy.getSize(id) | |||
viewParameters[PARAM_ID] = id | |||
return viewParameters | |||
end | end | ||
Line 244: | Line 194: | ||
--region Public methods | --region Public methods | ||
---main | |||
--- For calling from Template:Buildingbox. After handling the frame, forwards control to the primary method, findBoxType, then calls the view template with the compiled box data. Does not interface with any data modules. | |||
--- | --- | ||
---@param frame table the calling template's context | |||
---@return string wiki markup, constructed with the template view | |||
--- @param frame table | function Buildingbox.main(frame) | ||
--- @return string | |||
function Buildingbox. | local name = frame.args[ARG_NAME] | ||
if not name then | |||
error("You must specify the name of the building. Please see the template documentation for how to use the parameters") | |||
end | |||
local viewParameters = buildViewParameters(frame, name) | |||
if not viewParameters then | |||
error("No building found with name: " .. name .. ". Please see the template documentation for how to use the parameters") | |||
end | |||
-- Return the message if it's a string, otherwise proceed because it's a table. | |||
if type(viewParameters) == "string" then | |||
return viewParameters | |||
end | |||
return frame:expandTemplate{ title = VIEW_TEMPLATE, args = viewParameters } | |||
end | end | ||
Latest revision as of 18:57, 10 November 2024
Documentation for this module may be created at Module:Buildingbox/doc
--- Retrieves data for the specified building, resource, perk, etc. and sends the data over to the view, another template. --- --- @module Buildingbox local Buildingbox = {} --region Dependencies local BuildingDataProxy = require("Module:BuildingDataProxy") local SpecializationsData = mw.loadData("Module:SpecializationsData") local SpeciesData = mw.loadData("Module:SpeciesData") local Construction = require("Module:Construction") local ControllerUtilities = require("Module:ControllerUtilities") local VIEW_TEMPLATE = "Buildingbox/view" local VIEW_TEMPLATE_SPECIALIZATION_LINK = "Specialization_link/view" local VIEW_TEMPLATE_SPECIES_LINK = "Species_link/view" local TEMPLATE_RECIPE = "Recipe" --endregion --region Private constants local ARG_NAME = "name" local PARAM_TITLE = "title" local PARAM_SUBTITLE = "subtitle" local PARAM_DESCRIPTION = "description" local PARAM_SPECIALIZATION = "specialization" local PARAM_ICON_FILENAME = "iconfilename" local PARAM_MOVABLE = "movable" local PARAM_WORKPLACES = "workplaces" local PARAM_STORAGE = "storage" local PARAM_RECIPES = "recipes" local PARAM_CONSTRUCTION_COST = "construction" local PARAM_CITY_SCORE = "cityscore" local PARAM_CONSTRUCTION_TIME = "constructiontime" local PARAM_CONSTRUCTION_SIZE = "constructionsize" local PARAM_ID = "id" --endregion --region Private methods ---renderSpecializations takes the ID of a building and looks up its specializations, calls external view templates to convert those specializations into usable content strings for display, and returns those strings concatenated together for display by the calling scope. ---@param frame table the Mediawiki template calling context ---@param id string the unique ID of the building ---@return string a content string ready for display local function renderSpecializations(frame, id) local listOfSpecializationsAtBuilding = SpecializationsData.buildingSpecializations[id] if not listOfSpecializationsAtBuilding then return nil end local concatenatedStrings = "" for _, specializationIndex in ipairs(listOfSpecializationsAtBuilding) do -- Specialization link first local specializationData = SpecializationsData.specializations[specializationIndex] local specializationString = frame:expandTemplate{ title = VIEW_TEMPLATE_SPECIALIZATION_LINK, args = { ["iconfilename"] = specializationData[SpecializationsData.ICON_FILENAME], ["name"] = specializationData[SpecializationsData.NAME], ["type"] = specializationData[SpecializationsData.IS_COMFORTABLE] and "Comfort" or "Proficiency", ["iconsize"] = "small", }, } -- Species link second, but just the icon local speciesID = specializationData[SpecializationsData.SPECIES] local speciesString = frame:expandTemplate{ title = VIEW_TEMPLATE_SPECIES_LINK, args = { ["iconfilename"] = SpeciesData.species[speciesID][SpeciesData.ICON_FILENAME] .. ".png", ["name"] = SpeciesData.species[speciesID][SpeciesData.NAME], ["iconsize"] = "small", ["display"] = "notext", }, } -- Separate multiple entries with line break if #concatenatedStrings > 1 then concatenatedStrings = concatenatedStrings .. "<br />" end concatenatedStrings = concatenatedStrings .. specializationString .. " " .. speciesString end if #concatenatedStrings < 1 then return "None" end return concatenatedStrings end ---expandRecipeList ---@param frame table ---@param id table ---@return table local function expandRecipeList(frame, id) local recipeMarkup = frame:expandTemplate{ title = TEMPLATE_RECIPE, args = { ["building"] = BuildingDataProxy.getName(id), ["display"] = "list", } } if recipeMarkup and not string.match(recipeMarkup, "^No recipes found") then return recipeMarkup else return "" end end ---transformConstructionCosts ---Gets the construction costs for the specified building and calls the utility function, not as a template, but directly, to build a table from that data directly. --- ---@return string markup for a table of construction goods to display local function transformConstructionCosts(id) local constructionGoods = BuildingDataProxy.getConstructionCosts(id) if not constructionGoods then return nil end return "" .. Construction.makeTableFromData(constructionGoods) end ---buildViewParameters ---Populates a table of parameters for the view based on building data. --- ---Leverages the building proxy to federate the query out to the right data model without worrying about which one it's coming from: --- getCategory --- getCityScore --- getConstructionCosts (as [goodName] = stack size) --- getConstructionTime --- getDescription --- getIcon --- isMovable --- getName --- getNumberOfWorkplaces --- getSize (as "X x Y") --- getStorage --- ---@param frame table the Mediawiki template calling context ---@param name string the name of the building ---@return table of arguments for the view template local function buildViewParameters(frame, name) local id = BuildingDataProxy.getID(name) if not id then return nil end local viewParameters = {} viewParameters[PARAM_TITLE] = BuildingDataProxy.getName(id) viewParameters[PARAM_SUBTITLE] = BuildingDataProxy.getSecondCategory(id) .. "<br />" .. "(" .. BuildingDataProxy.getCategory(id) .. ")" viewParameters[PARAM_DESCRIPTION] = ControllerUtilities.findAndReplaceSpriteTagsWithFiles(BuildingDataProxy.getDescription(id), frame) viewParameters[PARAM_SPECIALIZATION] = renderSpecializations(frame, id) viewParameters[PARAM_ICON_FILENAME] = BuildingDataProxy.getIcon(id) viewParameters[PARAM_MOVABLE] = BuildingDataProxy.isMovable(id) and "true" viewParameters[PARAM_WORKPLACES] = BuildingDataProxy.getNumberOfWorkplaces(id) viewParameters[PARAM_RECIPES] = expandRecipeList(frame, id) viewParameters[PARAM_STORAGE] = BuildingDataProxy.getStorage(id) viewParameters[PARAM_CONSTRUCTION_COST] = transformConstructionCosts(id) viewParameters[PARAM_CITY_SCORE] = BuildingDataProxy.getCityScore(id) viewParameters[PARAM_CONSTRUCTION_TIME] = BuildingDataProxy.getConstructionTime(id) viewParameters[PARAM_CONSTRUCTION_SIZE] = BuildingDataProxy.getSize(id) viewParameters[PARAM_ID] = id return viewParameters end --endregion --region Public methods ---main --- For calling from Template:Buildingbox. After handling the frame, forwards control to the primary method, findBoxType, then calls the view template with the compiled box data. Does not interface with any data modules. --- ---@param frame table the calling template's context ---@return string wiki markup, constructed with the template view function Buildingbox.main(frame) local name = frame.args[ARG_NAME] if not name then error("You must specify the name of the building. Please see the template documentation for how to use the parameters") end local viewParameters = buildViewParameters(frame, name) if not viewParameters then error("No building found with name: " .. name .. ". Please see the template documentation for how to use the parameters") end -- Return the message if it's a string, otherwise proceed because it's a table. if type(viewParameters) == "string" then return viewParameters end return frame:expandTemplate{ title = VIEW_TEMPLATE, args = viewParameters } end --endregion return Buildingbox