Module:Buildings table: Difference between revisions
From Beyond These Stars Official Wiki
shifting classes; removing one-row option as the data model doesn't align with this approach. |
changed column order in table; added fallback to vector icon when portrait icon doesn't exist |
||
| Line 2: | Line 2: | ||
Test in Scribunto console with: | Test in Scribunto console with: | ||
=p.render() | =p.render() | ||
]]-- | ]]-- | ||
local p = {} | local p = {} | ||
| Line 22: | Line 19: | ||
local TOP_LEVEL_CLASS = "bts-table-buildings" | local TOP_LEVEL_CLASS = "bts-table-buildings" | ||
local TABLE_CLASS = "wikitable sortable" | local TABLE_CLASS = "wikitable sortable" | ||
local UNSORTABLE_CLASS = "unsortable" | |||
local RESOURCE_LIST_CLASS = "bts-resource-list" | local RESOURCE_LIST_CLASS = "bts-resource-list" | ||
local RESOURCE_ICON_CLASS = "bts-resource-icon" | local RESOURCE_ICON_CLASS = "bts-resource-icon" | ||
local LARGE_ICON_SIZE = "96px" | |||
local SMALL_ICON_SIZE = "32px" | local SMALL_ICON_SIZE = "32px" | ||
| Line 38: | Line 37: | ||
local function add_header_row(wikitable, buildings) | local function add_header_row(wikitable, buildings) | ||
local header = wikitable:tag("tr") | local header = wikitable:tag("tr") | ||
header:tag("th"):addClass(UNSORTABLE_CLASS):wikitext("Icon") | |||
header:tag("th"):wikitext("Name") | header:tag("th"):wikitext("Name") | ||
header:tag("th"):wikitext("Category") | header:tag("th"):wikitext("Category") | ||
header:tag("th"):wikitext("Workers") | header:tag("th"):wikitext("Workers") | ||
header:tag("th"):wikitext("Production") | header:tag("th"):wikitext("Production") | ||
header:tag("th"):wikitext("Req. Power") | header:tag("th"):wikitext("Req. Power?") | ||
header:tag("th"):addClass(UNSORTABLE_CLASS):wikitext("Construction Costs") | |||
header:tag("th"):wikitext("Tech Prerequisite") | |||
end | |||
--- Resolves a file name for the icon for the building. | |||
---@param building Building | |||
---@return string|nil file_name | |||
local function resolve_icon_file_name(building) | |||
if building and building.portrait_icon then | |||
local portrait_file_name = "File:" .. building.portrait_icon .. ".png" | |||
return portrait_file_name | |||
end | |||
if building and building.icon then | |||
local vector_file_name = "File:" .. building.icon .. ".png" | |||
return vector_file_name | |||
end | |||
return nil | |||
end | |||
--- Renders markup for an icon for the building. | |||
---@param building Building | |||
---@return string wikitext | |||
local function render_icon(building) | |||
if not building or not building.icon then return "" end | |||
local file_name = resolve_icon_file_name(building) | |||
if not file_name then return "" end | |||
local icon_size = "x" .. LARGE_ICON_SIZE | |||
local name = building.display_name | |||
local link_attr = "link=" .. building.display_name | |||
return "[[" .. file_name .. "|" .. icon_size .. "|" .. name .. "|" .. link_attr .. "]]" | |||
end | end | ||
| Line 73: | Line 105: | ||
end | end | ||
tr:tag("td"):wikitext(link_markup) | tr:tag("td"):wikitext(link_markup) | ||
end | end | ||
| Line 139: | Line 141: | ||
end | end | ||
return TEXT_IS_NOT_POWERED | return TEXT_IS_NOT_POWERED | ||
end | |||
--- Builds an inner list of construction resources. | |||
---@param building Building | |||
---@return HtmlNode node | |||
local function build_construction_resources(building) | |||
local tbl = mw.html.create("table"):addClass(RESOURCE_LIST_CLASS) | |||
if not building.construction_resources or building.construction_resources == {} then return tbl end | |||
for _, pair in ipairs(building.construction_resources) do | |||
local tr = tbl:tag("tr") | |||
tr:tag("td"):wikitext(pair.amount) | |||
local resource_record = Resource_Data_Module.get_resource(pair.name) | |||
add_resource_icon(tr, resource_record) | |||
add_resource_link(tr, resource_record) | |||
end | |||
return tbl | |||
end | |||
--- Renders a link to the prerequisite building in the tech tree for the given building. | |||
---@param building Building | |||
---@return string wikitext | |||
local function render_tech_prerequisite(building) | |||
if not building.tech_tree_previous or building.tech_tree_previous == "" then return "" end | |||
local prerequisite_name = Building_Data_Module.get_building_by_id(building.tech_tree_previous) | |||
if not prerequisite_name then return "" end | |||
return "[[" .. prerequisite_name .. "]]" | |||
end | end | ||
| Line 148: | Line 180: | ||
local function build_row(building) | local function build_row(building) | ||
local row = mw.html.create("tr") | local row = mw.html.create("tr") | ||
row:tag("td"):wikitext(render_icon(building)) | |||
row:tag("td"):wikitext("[[" .. building.display_name .. "]]") | row:tag("td"):wikitext("[[" .. building.display_name .. "]]") | ||
if building.category and building.category ~= "" then | if building.category and building.category ~= "" then | ||
row:tag("td"):wikitext("[[Category:" .. building.category .. " Buildings" .. "|" .. building.category .. "]]") | row:tag("td"):wikitext("[[:Category:" .. building.category .. " Buildings" .. "|" .. building.category .. "]]") | ||
else | |||
row:tag("td"):wikitext("") | |||
end | end | ||
row:tag("td"):wikitext(building.max_peeps or "") | |||
row:tag("td"):node(build_produced_resources(building)) | |||
row:tag("td"):wikitext(render_powered(building)) | |||
row:tag("td"):node(build_construction_resources(building)) | row:tag("td"):node(build_construction_resources(building)) | ||
row:tag("td"):wikitext(render_tech_prerequisite(building)) | row:tag("td"):wikitext(render_tech_prerequisite(building)) | ||
return row | return row | ||
end | end | ||
Revision as of 03:47, 25 September 2026
Documentation for this module may be created at Module:Buildings table/doc
--[[
Test in Scribunto console with:
=p.render()
]]--
local p = {}
local Building_Data_Module = require("Module:Building_data")
local Resource_Data_Module = require("Module:Resource_data")
--#region html building helper functions
---@diagnostic disable-next-line: duplicate-doc-alias
---@alias HtmlNode table
local TOP_LEVEL_CLASS = "bts-table-buildings"
local TABLE_CLASS = "wikitable sortable"
local UNSORTABLE_CLASS = "unsortable"
local RESOURCE_LIST_CLASS = "bts-resource-list"
local RESOURCE_ICON_CLASS = "bts-resource-icon"
local LARGE_ICON_SIZE = "96px"
local SMALL_ICON_SIZE = "32px"
local TEXT_IS_POWERED = "Yes [[File:Resource_Power.png|32px|Power]]"
local TEXT_IS_NOT_POWERED = "No"
--- Adds the header row to the provided html node.
---@param wikitable HtmlNode wikitable
---@param buildings Building[]
local function add_header_row(wikitable, buildings)
local header = wikitable:tag("tr")
header:tag("th"):addClass(UNSORTABLE_CLASS):wikitext("Icon")
header:tag("th"):wikitext("Name")
header:tag("th"):wikitext("Category")
header:tag("th"):wikitext("Workers")
header:tag("th"):wikitext("Production")
header:tag("th"):wikitext("Req. Power?")
header:tag("th"):addClass(UNSORTABLE_CLASS):wikitext("Construction Costs")
header:tag("th"):wikitext("Tech Prerequisite")
end
--- Resolves a file name for the icon for the building.
---@param building Building
---@return string|nil file_name
local function resolve_icon_file_name(building)
if building and building.portrait_icon then
local portrait_file_name = "File:" .. building.portrait_icon .. ".png"
return portrait_file_name
end
if building and building.icon then
local vector_file_name = "File:" .. building.icon .. ".png"
return vector_file_name
end
return nil
end
--- Renders markup for an icon for the building.
---@param building Building
---@return string wikitext
local function render_icon(building)
if not building or not building.icon then return "" end
local file_name = resolve_icon_file_name(building)
if not file_name then return "" end
local icon_size = "x" .. LARGE_ICON_SIZE
local name = building.display_name
local link_attr = "link=" .. building.display_name
return "[[" .. file_name .. "|" .. icon_size .. "|" .. name .. "|" .. link_attr .. "]]"
end
--- Adds an icon for a resource to the provided html table row.
---@param tr HtmlNode tr
---@param resource ResourceRecord
local function add_resource_icon(tr, resource)
local icon_markup = ""
if resource and resource.icon then
local file_name = "File:" .. resource.icon .. ".png"
local icon_size = "x" .. SMALL_ICON_SIZE
local name = resource.display_name
local link_attr = "link=" .. resource.display_name
icon_markup = "[[" .. file_name .. "|" .. icon_size .. "|" .. name .. "|" .. link_attr .. "]]"
end
tr:tag("td"):tag("span"):addClass(RESOURCE_ICON_CLASS):wikitext(icon_markup)
end
--- Adds a link for a resource to the provided html table row.
---@param tr HtmlNode tr
---@param resource ResourceRecord
local function add_resource_link(tr, resource)
local link_markup = ""
if resource and resource.display_name then
link_markup = "[[" .. resource.display_name .. "]]"
end
tr:tag("td"):wikitext(link_markup)
end
--- Builds an inner list of produced resources.
---@param building Building
---@return HtmlNode node
local function build_produced_resources(building)
local tbl = mw.html.create("table"):addClass(RESOURCE_LIST_CLASS)
if not building or not building.tasks or #building.tasks == 0 then return tbl end
for _, task in ipairs(building.tasks) do
for _, output_io in ipairs(task.outputs) do
local resource = Resource_Data_Module.get_resource(output_io.resource)
local tr = tbl:tag("tr")
add_resource_icon(tr, resource)
add_resource_link(tr, resource)
end
end
return tbl
end
--- Renders a statement about whether the given building requires power.
---@param building Building
---@return string wikitext
local function render_powered(building)
if not building or not building.tasks or #building.tasks == 0 then return TEXT_IS_NOT_POWERED end
for _, task in ipairs(building.tasks) do
for _, input_io in ipairs(task.inputs) do
if input_io.resource == Resource_Data_Module.POWER_RESOURCE_NAME then
return TEXT_IS_POWERED
end
end
end
return TEXT_IS_NOT_POWERED
end
--- Builds an inner list of construction resources.
---@param building Building
---@return HtmlNode node
local function build_construction_resources(building)
local tbl = mw.html.create("table"):addClass(RESOURCE_LIST_CLASS)
if not building.construction_resources or building.construction_resources == {} then return tbl end
for _, pair in ipairs(building.construction_resources) do
local tr = tbl:tag("tr")
tr:tag("td"):wikitext(pair.amount)
local resource_record = Resource_Data_Module.get_resource(pair.name)
add_resource_icon(tr, resource_record)
add_resource_link(tr, resource_record)
end
return tbl
end
--- Renders a link to the prerequisite building in the tech tree for the given building.
---@param building Building
---@return string wikitext
local function render_tech_prerequisite(building)
if not building.tech_tree_previous or building.tech_tree_previous == "" then return "" end
local prerequisite_name = Building_Data_Module.get_building_by_id(building.tech_tree_previous)
if not prerequisite_name then return "" end
return "[[" .. prerequisite_name .. "]]"
end
--- Adds a row to the provided html node.
---@param building Building
---@return HtmlNode row
local function build_row(building)
local row = mw.html.create("tr")
row:tag("td"):wikitext(render_icon(building))
row:tag("td"):wikitext("[[" .. building.display_name .. "]]")
if building.category and building.category ~= "" then
row:tag("td"):wikitext("[[:Category:" .. building.category .. " Buildings" .. "|" .. building.category .. "]]")
else
row:tag("td"):wikitext("")
end
row:tag("td"):wikitext(building.max_peeps or "")
row:tag("td"):node(build_produced_resources(building))
row:tag("td"):wikitext(render_powered(building))
row:tag("td"):node(build_construction_resources(building))
row:tag("td"):wikitext(render_tech_prerequisite(building))
return row
end
--- Builds a table of buildings.
---@param buildings Building[]
---@return string wikitext
local function build_table(buildings)
---@type HtmlNode
local div = mw.html.create("div")
div:addClass(TOP_LEVEL_CLASS)
local wikitable = div:tag("table"):addClass(TABLE_CLASS)
add_header_row(wikitable, buildings)
for _, building in ipairs(buildings) do
wikitable:node(build_row(building))
end
return tostring(div)
end
--#endregion
--- `#invoke` entry point.
---@param frame table Scribunto frame from `#invoke`.
---@return string wikitext table wikitext code
function p.render(frame)
local buildings = Building_Data_Module.get_all_buildings()
if #buildings == 0 then return "" end
local wikitext = build_table(buildings)
return wikitext
end
return p


