Module:Buildingbox: Difference between revisions

From Against the Storm Official Wiki
m (species link view template had to change)
(Updating to new secondary categories)
 
(4 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.
--- Retrieves data for the specified building, resource, perk, etc. and sends the data over to the view, another template.
---
---
Line 9: Line 8:
--region Dependencies
--region Dependencies


--Some dependencies in this module are loaded lazily, but we want them scoped to the entire module, not their local functions
local BuildingDataProxy = require("Module:BuildingDataProxy")
local WorkshopsData
local InstitutionsData
local FarmsData
local CampsData
local CollectorsData
 
local SpecializationsData
local SpeciesData


local SpecializationsData = mw.loadData("Module:SpecializationsData")
local SpeciesData = mw.loadData("Module:SpeciesData")
local Construction = require("Module:Construction")
local ControllerUtilities = require("Module:ControllerUtilities")
local ControllerUtilities = require("Module:ControllerUtilities")


local ViewTemplate = "Template:Infobox"
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
--endregion
Line 53: Line 50:


---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.
---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 id string the unique ID of the building
---@return string a content string ready for display
---@return string a content string ready for display
local function renderSpecializations(id)
local function renderSpecializations(frame, id)
 
    SpecializationsData = mw.loadData("Module:SpecializationsData")
    SpeciesData = mw.loadData("Module:SpeciesData")
    local frame = mw.getCurrentFrame()


     local listOfSpecializationsAtBuilding = SpecializationsData.buildingSpecializations[id]
     local listOfSpecializationsAtBuilding = SpecializationsData.buildingSpecializations[id]
Line 73: Line 67:
         local specializationData = SpecializationsData.specializations[specializationIndex]
         local specializationData = SpecializationsData.specializations[specializationIndex]
         local specializationString = frame:expandTemplate{
         local specializationString = frame:expandTemplate{
             title = "Specialization",
             title = VIEW_TEMPLATE_SPECIALIZATION_LINK,
             args = {
             args = {
                 ["iconfilename"] = specializationData[SpecializationsData.ICON_FILENAME],
                 ["iconfilename"] = specializationData[SpecializationsData.ICON_FILENAME],
                 ["name"] = specializationData[SpecializationsData.NAME],
                 ["name"] = specializationData[SpecializationsData.NAME],
                 ["type"] = specializationData[SpecializationsData.IS_COMFORTABLE] and "Comfort" or "Proficiency",
                 ["type"] = specializationData[SpecializationsData.IS_COMFORTABLE] and "Comfort" or "Proficiency",
                 ["size"] = "small",
                 ["iconsize"] = "small",
             }, }
             }, }


Line 84: Line 78:
         local speciesID = specializationData[SpecializationsData.SPECIES]
         local speciesID = specializationData[SpecializationsData.SPECIES]
         local speciesString = frame:expandTemplate{
         local speciesString = frame:expandTemplate{
             title = "Species",
             title = VIEW_TEMPLATE_SPECIES_LINK,
             args = {
             args = {
                 ["iconfilename"] = SpeciesData.species[speciesID][SpeciesData.ICON_FILENAME] .. ".png",
                 ["iconfilename"] = SpeciesData.species[speciesID][SpeciesData.ICON_FILENAME] .. ".png",
                 ["name"] = SpeciesData.species[speciesID][SpeciesData.NAME],
                 ["name"] = SpeciesData.species[speciesID][SpeciesData.NAME],
                 ["size"] = "small",
                 ["iconsize"] = "small",
                 ["display"] = "notext",
                 ["display"] = "notext",
             }, }
             }, }
Line 109: Line 103:




-- Building interface:
---expandRecipeList
-- getCategory
---@param frame table
-- getCityScore
---@param id table
-- getConstructionCosts (as [goodName] = stack size)
---@return table
-- getConstructionTime
local function expandRecipeList(frame, id)
-- 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)
    local recipeMarkup = frame:expandTemplate{
        title = TEMPLATE_RECIPE,
        args = {
            ["building"] = BuildingDataProxy.getName(id),
            ["display"] = "list",
        }
    }


     WorkshopsData = require("Module:WorkshopsData")
     if recipeMarkup and not string.match(recipeMarkup, "^No recipes found") then
 
         return recipeMarkup
    local id = WorkshopsData.getWorkshopID(name)
    if not id then
         return false
     else
     else
         return buildViewParameters(id, WorkshopsData, "Production Building")
         return ""
     end
     end
end
end


local function tryInstitutionsData(name)


    InstitutionsData = require("Module:InstitutionsData")


    local id = InstitutionsData.getInstitutionID(name)
---transformConstructionCosts
    if not id then
---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 false
---
    else
---@return string markup for a table of construction goods to display
        return buildViewParameters(id, InstitutionsData, "Service Building")
local function transformConstructionCosts(id)
    end
end


local function tryFarmsData(name)
    local constructionGoods = BuildingDataProxy.getConstructionCosts(id)


    FarmsData = require("Module:FarmsData")
     if not constructionGoods then
 
         return nil
    local id = FarmsData.getFarmID(name)
     if not id then
         return false
    else
        return buildViewParameters(id, FarmsData, "Farm")
     end
     end
end
local function tryCampsData(name)
    CampsData = require("Module:CampsData")


     local id = CampsData.getCampID(name)
     return "" .. Construction.makeTableFromData(constructionGoods)
    if not id then
        return false
    else
        return buildViewParameters(id, CampsData, "Gathering Camp")
    end
end
end


local function tryCollectorsData(name)


    CollectorsData = require("Module:CollectorsData")
---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 = CollectorsData.getCollectorID(name)
     local id = BuildingDataProxy.getID(name)
     if not id then
     if not id then
         return false
         return nil
    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
                        return("No building found with name: " .. name .. ".")
                    end
                end
            end
        end
     end
     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
     return viewParameters
Line 250: Line 203:
     local name = frame.args[ARG_NAME]
     local name = frame.args[ARG_NAME]
     if not name then
     if not name then
         error("You must specify the name of the building. Please see the template documentation for how to use the parameters.")
         error("You must specify the name of the building. Please see the template documentation for how to use the parameters")
     end
     end


     local viewParameters = findBoxType(name)
     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.
     -- Return the message if it's a string, otherwise proceed because it's a table.
Line 260: Line 216:
     end
     end


     return frame:expandTemplate{ title = ViewTemplate, args = viewParameters }
     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 .. "&nbsp;" .. 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