Module:Buildingbox
From Against the Storm Official Wiki
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
--Some dependencies in this module are loaded lazily, but we want them scoped to the entire module, not their local functions
local WorkshopsData
local InstitutionsData
local FarmsData
local CampsData
local CollectorsData
local SpecializationsData
local SpeciesData
local ControllerUtilities = require("Module:ControllerUtilities")
local VIEW_TEMPLATE = "Buildingbox/view"
--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 id string the unique ID of the building
---@return string a content string ready for display
local function renderSpecializations(id)
SpecializationsData = mw.loadData("Module:SpecializationsData")
SpeciesData = mw.loadData("Module:SpeciesData")
local frame = mw.getCurrentFrame()
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 = "Specialization",
args = {
["iconfilename"] = specializationData[SpecializationsData.ICON_FILENAME],
["name"] = specializationData[SpecializationsData.NAME],
["type"] = specializationData[SpecializationsData.IS_COMFORTABLE] and "Comfort" or "Proficiency",
["size"] = "small",
}, }
-- Species link second, but just the icon
local speciesID = specializationData[SpecializationsData.SPECIES]
local speciesString = frame:expandTemplate{
title = "Species_link/view",
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
-- Building interface:
-- getCategory
-- getCityScore
-- getConstructionCosts (as [goodName] = stack size)
-- getConstructionTime
-- getDescription
-- getIcon
-- isMovable
-- getName
-- getNumberOfWorkplaces
-- getSize (as "X x Y")
-- getStorage
local function buildViewParameters(id, buildingInterface, subtitlePrefix)
local frame = mw.getCurrentFrame()
local viewParameters = {}
viewParameters[PARAM_TITLE] = buildingInterface.getName(id)
viewParameters[PARAM_SUBTITLE] = subtitlePrefix .. " (" .. buildingInterface.getCategory(id) .. ")"
viewParameters[PARAM_DESCRIPTION] = ControllerUtilities.findAndReplaceSpriteTagsWithFiles(buildingInterface.getDescription(id), frame)
viewParameters[PARAM_SPECIALIZATION] = renderSpecializations(id)
viewParameters[PARAM_ICON_FILENAME] = buildingInterface.getIcon(id)
viewParameters[PARAM_MOVABLE] = buildingInterface.isMovable(id) and "true"
viewParameters[PARAM_WORKPLACES] = buildingInterface.getNumberOfWorkplaces(id)
viewParameters[PARAM_RECIPES] = frame:expandTemplate{ title = "Recipe", args = { ["building"] = buildingInterface.getName(id), ["display"] = "list", }, }
viewParameters[PARAM_STORAGE] = buildingInterface.getStorage(id)
viewParameters[PARAM_CONSTRUCTION_COST] = frame:expandTemplate{ title = "Construction", args = buildingInterface.getConstructionCosts(id) }
viewParameters[PARAM_CITY_SCORE] = buildingInterface.getCityScore(id)
viewParameters[PARAM_CONSTRUCTION_TIME] = buildingInterface.getConstructionTime(id)
viewParameters[PARAM_CONSTRUCTION_SIZE] = buildingInterface.getSize(id)
viewParameters[PARAM_ID] = id
return viewParameters
end
local function tryWorkshopsData(name)
WorkshopsData = require("Module:WorkshopsData")
local id = WorkshopsData.getID(name)
if not id then
return false
else
return buildViewParameters(id, WorkshopsData, "Production Building")
end
end
local function tryInstitutionsData(name)
InstitutionsData = require("Module:InstitutionsData")
local id = InstitutionsData.getID(name)
if not id then
return false
else
return buildViewParameters(id, InstitutionsData, "Service Building")
end
end
local function tryFarmsData(name)
FarmsData = require("Module:FarmsData")
local id = FarmsData.getID(name)
if not id then
return false
else
return buildViewParameters(id, FarmsData, "Farm")
end
end
local function tryCampsData(name)
CampsData = require("Module:CampsData")
local id = CampsData.getID(name)
if not id then
return false
else
return buildViewParameters(id, CampsData, "Gathering Camp")
end
end
local function tryCollectorsData(name)
CollectorsData = require("Module:CollectorsData")
local id = CollectorsData.getID(name)
if not id then
return false
else
return buildViewParameters(id, CollectorsData, "Extraction Building")
end
end
---findBoxType
--- Handles data only, does not interface with the Buildingbox view.
---@param name string the name of the building about which to retrieve data
---@return table the essential data about the building extracted
local function findBoxType(name)
-- Lazy-load of external data, since it's expensive. Start with the most likely so that most pages load as fast as possible.
local viewParameters = tryWorkshopsData(name)
if not viewParameters then
viewParameters = tryInstitutionsData(name)
if not viewParameters then
viewParameters = tryFarmsData(name)
if not viewParameters then
viewParameters = tryCollectorsData(name)
if not viewParameters then
viewParameters = tryCampsData(name)
if not viewParameters then
error("No building found with name: " .. name .. ". Please see the template documentation for how to use the parameters")
end
end
end
end
end
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 = findBoxType(name)
-- 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


