Module:Buildingbox
From Against the Storm Official Wiki
Documentation for this module may be created at Module:Buildingbox/doc
--- --- Module to create an infobox for displaying on a building's wiki page. --- --- Shows the facts from the data about the specified building in an easy-to- --- read table, with a large icon, information, categories, and the flavor --- text. --- --- This should be invoked from Template:Buildingbox with the parameter of the --- building whose infobox should be shown. See the template documentation for --- more information about parameters and errors and to see examples. --- --- @module Buildingbox local Buildingbox = {} local StyleUtils = require("Module:StyleUtils") local Infobox = require("Module:Infobox") local WorkshopsData = require("Module:WorkshopsData") local InstitutionsData = require("Module:InstitutionsData") local CampsData = require("Module:CampsData") local FarmsData = require("Module:FarmsData") local CollectorsData = require("Module:CollectorsData") --region Private constants local ARGS = { ["name"] = "name", ["purpose"] = "purpose", ["species_preference"] = "species_preference", ["specializations"] = "specializations", } --endregion --region Private methods --- --- Shortcut method to expand a template with parameters --- ---@param buildingName string the name of the building ---@return string html markup returned by the template local function expandRecipeList(buildingName) return mw.getCurrentFrame():expandTemplate{ title="Recipe", args={ building= buildingName, display="list" } } end --- --- Shortcut method since the size methods return two values. --- ---@param buildingName string the name of the building to check ---@return number, number the X and Y sizes local function distributeSizes(buildingName) local sizeX, sizeY = WorkshopsData.getWorkshopSize(buildingName) if sizeX and sizeY then return sizeX, sizeY end sizeX, sizeY = InstitutionsData.getInstitutionSize(buildingName) if sizeX and sizeY then return sizeX, sizeY end sizeX, sizeY = CampsData.getCampSize(buildingName) if sizeX and sizeY then return sizeX, sizeY end sizeX, sizeY = FarmsData.getFarmSize(buildingName) if sizeX and sizeY then return sizeX, sizeY end sizeX, sizeY = CollectorsData.getCollectorSize(buildingName) return sizeX, sizeY end --- --- Builds using the provided wikiInfobox a few header items. --- ---@param wikiInfobox table mw.html object into which we're building this ---@param buildingName string the name of the building the infobox is about ---@return table the Mediawiki html object into which we've been adding things local function makeHeaderContent(wikiInfobox, buildingName) -- Grab the data we'll use to populate this. local description = WorkshopsData.getWorkshopDescription(buildingName) or InstitutionsData.getInstitutionDescription(buildingName) or CampsData.getCampDescription(buildingName) or FarmsData.getFarmDescription(buildingName) or CollectorsData.getCollectorDescription(buildingName) local iconFilename = WorkshopsData.getWorkshopIcon(buildingName) or InstitutionsData.getInstitutionIcon(buildingName) or CampsData.getCampIcon(buildingName) or FarmsData.getFarmIcon(buildingName) or CollectorsData.getCollectorIcon(buildingName) -- Start the header area local header = Infobox.startNewHeader(wikiInfobox) Infobox.makeTitle(header, buildingName) Infobox.makeFlavorText(header, description) Infobox.makeTitleIcon(header, iconFilename) return wikiInfobox end --- --- Builds using the provided wikiInfobox a subtable to lay out headers and --- fields. --- ---@param wikiInfobox table mw.html object into which we're building this ---@param buildingName string the name of the good the infobox is about ---@param params table of template parameters ---@return table the Mediawiki html object into which we've been adding things local function makeInnerContent(wikiInfobox, buildingName, params) -- Grab the data we'll use to populate this. local category = WorkshopsData.getWorkshopCategory(buildingName) or InstitutionsData.getInstitutionCategory(buildingName) or CampsData.getCampCategory(buildingName) or FarmsData.getFarmCategory(buildingName) or CollectorsData.getCollectorCategory(buildingName) local recipesTable = WorkshopsData.getAllWorkshopRecipes(buildingName) or InstitutionsData.getAllInstitutionRecipes(buildingName) or CampsData.getAllCampRecipes(buildingName) or FarmsData.getAllFarmRecipes(buildingName) or CollectorsData.getAllCollectorRecipes(buildingName) local isMovable = WorkshopsData.isWorkshopMovable(buildingName) or InstitutionsData.isInstitutionMovable(buildingName) or CampsData.isCampMovable(buildingName) or FarmsData.isFarmMovable(buildingName) or CollectorsData.isCollectorMovable(buildingName) local isEssential = WorkshopsData.isWorkshopInitiallyEssential(buildingName) or InstitutionsData.isInstitutionInitiallyEssential(buildingName) or CampsData.isCampInitiallyEssential(buildingName) or FarmsData.isFarmInitiallyEssential(buildingName) or CollectorsData.isCollectorInitiallyEssential(buildingName) local sizeX, sizeY = distributeSizes(buildingName) local range = CampsData.getCampArea(buildingName) -- Workshops and -- Institutions don't have a range/area or FarmsData.getFarmArea(buildingName) -- Collectors don't have a range local storageCap = WorkshopsData.getWorkshopStorage(buildingName) -- Institutions don't have storage or CampsData.getCampStorage(buildingName) or FarmsData.getFarmStorage(buildingName) or CollectorsData.getCollectorStorage(buildingName) local numWorkplaces = WorkshopsData.getWorkshopNumberOfWorkplaces(buildingName) or InstitutionsData.getInstitutionNumberOfWorkplaces(buildingName) or CampsData.getCampNumberOfWorkplaces(buildingName) or FarmsData.getFarmNumberOfWorkplaces(buildingName) or CollectorsData.getCollectorNumberOfWorkplaces(buildingName) local constructionTime = WorkshopsData.getWorkshopConstructionTime(buildingName) or InstitutionsData.getInstitutionConstructionTime(buildingName) or CampsData.getCampConstructionTime(buildingName) or FarmsData.getFarmConstructionTime(buildingName) or CollectorsData.getCollectorConstructionTime(buildingName) local constructionGoods = WorkshopsData.getAllWorkshopRequiredGoods(buildingName) or InstitutionsData.getAllInstitutionRequiredGoods(buildingName) or CampsData.getAllCampRequiredGoods(buildingName) or FarmsData.getAllFarmRequiredGoods(buildingName) or CollectorsData.getAllCollectorRequiredGoods(buildingName) local buildingID = WorkshopsData.getWorkshopID(buildingName) or InstitutionsData.getInstitutionID(buildingName) or CampsData.getCampID(buildingName) or FarmsData.getFarmID(buildingName) or CollectorsData.getCollectorID(buildingName) -- Start the inner table local innerTable = Infobox.startNewInnerTable(wikiInfobox) -- we'll reuse this to mark where separators are needed in the table local needsSeparator = false -- Start with the things from the parameters, if any for paramTitle, paramValue in pairs(params or {}) do if paramTitle ~= nil and paramValue ~= nil then Infobox.makeInnerRow(innerTable, paramValue, false, Infobox.toTitleCase(paramTitle), paramValue) -- Require a separator if there were any parameters. needsSeparator = true end end needsSeparator = Infobox.makeInnerRow(innerTable, category, needsSeparator, Infobox.TITLE_CATEGORY, Infobox.makeCategoryIcon(category, false) .. StyleUtils.NBSP .. category) needsSeparator = Infobox.makeInnerRow(innerTable, recipesTable and #recipesTable > 0, needsSeparator, Infobox.TITLE_RECIPES, expandRecipeList(buildingName)) needsSeparator = true needsSeparator = Infobox.makeInnerRow(innerTable, isMovable, needsSeparator, Infobox.TITLE_MOVABLE, isMovable and "Yes" or "No") needsSeparator = Infobox.makeInnerRow(innerTable, isEssential, needsSeparator, Infobox.TITLE_ESSENTIAL, isEssential and "Yes" or "No") needsSeparator = Infobox.makeInnerRow(innerTable, sizeX and sizeY, needsSeparator, Infobox.TITLE_SIZE, sizeX .. " × " .. sizeY) needsSeparator = Infobox.makeInnerRow(innerTable, range, needsSeparator, Infobox.TITLE_RANGE, range) needsSeparator = Infobox.makeInnerRow(innerTable, storageCap, needsSeparator, Infobox.TITLE_STORAGE_CAPACITY, storageCap) needsSeparator = true needsSeparator = Infobox.makeInnerRow(innerTable, numWorkplaces, needsSeparator, Infobox.TITLE_WORKPLACES, numWorkplaces) needsSeparator = true needsSeparator = Infobox.makeInnerRow(innerTable, constructionTime, needsSeparator, Infobox.TITLE_CONSTRUCTION_TIME, constructionTime) needsSeparator = Infobox.makeInnerRow(innerTable, constructionGoods, needsSeparator, Infobox.TITLE_CONSTRUCTION_COST, Infobox.writeRequiredGoodsRows(constructionGoods) ) needsSeparator = true needsSeparator = Infobox.makeInnerRow(innerTable, buildingID, needsSeparator, Infobox.TITLE_ID, "'" .. buildingID .. "'") -- Close the inner table, and return it with the passed context Infobox.endInnerTable(wikiInfobox, innerTable) return wikiInfobox end --endregion --region Public methods --- --- Creates an html and wiki markup to display the data in an infobox. --- --- @param frame table from template's calling context --- @return string of html and wiki markup function Buildingbox.renderBuildingbox(frame) -- Every building must have a name. local buildingName = frame.args[ARGS.name] if not buildingName or buildingName == "" then return "You must specify the name of the building. See [[Template:Buildingbox]] for examples." end -- Use this method here to check to see whether the provided name is valid. if not ( WorkshopsData.getWorkshopID(buildingName) or InstitutionsData.getInstitutionID(buildingName) or CampsData.getCampID(buildingName) or FarmsData.getFarmID(buildingName) or CollectorsData.getCollectorID(buildingName) ) then return "Buildingbox can't find the specified building: " .. buildingName .. "." end -- Additional template parameters, may or may not be present. local purpose = frame.args[ARGS.purpose] local speciesPref = frame.args[ARGS.species_preference] local specializations = frame.args[ARGS.specializations] local wikiInfobox = Infobox.startNewInfobox() makeHeaderContent(wikiInfobox, buildingName) makeInnerContent(wikiInfobox, buildingName, { [ARGS.purpose] = purpose, [ARGS.species_preference] = speciesPref, [ARGS.specializations] = specializations }) return wikiInfobox end --endregion return Buildingbox