Module:Building infobox: Difference between revisions

From Beyond These Stars Official Wiki
added back the subheader for the building tasks
adds generic category too
 
(2 intermediate revisions by the same user not shown)
Line 34: Line 34:
local RESOURCE_ICON_CLASS = "bts-resource-icon"
local RESOURCE_ICON_CLASS = "bts-resource-icon"


local LARGE_ICON_SIZE = "168px"
local MEDIUM_ICON_SIZE = "96px"
local SMALL_ICON_SIZE = "32px"
local SMALL_ICON_SIZE = "32px"


Line 46: Line 48:
local function render_icon_markup(building)
local function render_icon_markup(building)
   local icon_filename
   local icon_filename
  local size = LARGE_ICON_SIZE
   if building.portrait_icon then
   if building.portrait_icon then
     icon_filename = building.portrait_icon .. ".png"
     icon_filename = building.portrait_icon .. ".png"
   -- elseif building.icon then
   elseif building.icon then
  --  icon_filename = building.icon .. ".png"
    icon_filename = building.icon .. ".png"
    size = MEDIUM_ICON_SIZE
   else
   else
     return ""
     return ""
   end
   end
   local image_markup = "[[File:" .. icon_filename .. "|" .. building.name .. "|link=" .. building.name .. "]]"
   local image_markup = "[[File:" .. icon_filename .. "|".. size .. "|" .. building.name .. "|link=]]"
   return image_markup
   return image_markup
end
end
Line 75: Line 79:
---@param building Building
---@param building Building
local function add_description(div, building)
local function add_description(div, building)
  if not building.description or building.description == "" then return end
   local inner_div = div:tag("div"):addClass(DESCRIPTION_CLASS)
   local inner_div = div:tag("div"):addClass(DESCRIPTION_CLASS)
   local description = building.description:gsub("<hb>", ""):gsub("</hb>", "")
   local description = building.description:gsub("<hb>", ""):gsub("</hb>", "")
Line 98: Line 101:
---@param building Building
---@param building Building
local function add_tech_prerequisite(div, building)
local function add_tech_prerequisite(div, building)
  if not building.tech_tree_previous or building.tech_tree_previous == {} then return end
   local inner_div = div:tag("div"):addClass(TECH_TREE_CLASS)
   local inner_div = div:tag("div"):addClass(TECH_TREE_CLASS)
   local check_icon = "[[File:UI teal open checkmark.png|x16px|link=]]"
   local check_icon = "[[File:UI teal open checkmark.png|x16px|link=]]"
Line 138: Line 140:
---@param building Building
---@param building Building
local function add_construction(div, building)
local function add_construction(div, building)
  if not building.construction_resources or building.construction_resources == {} then return end
   local tbl = div:tag("div"):addClass(CONSTRUCTION_CLASS)
   local tbl = div:tag("div"):addClass(CONSTRUCTION_CLASS)
       :tag("table"):addClass(CONSTRUCTION_TABLE_CLASS)
       :tag("table"):addClass(CONSTRUCTION_TABLE_CLASS)
Line 156: Line 157:
---@param building Building
---@param building Building
local function add_tasks(div, building)
local function add_tasks(div, building)
  if not building.tasks or building.tasks == {} then return end
   local tbl = div:tag("div"):addClass(TASKS_CLASS)
   local tbl = div:tag("div"):addClass(TASKS_CLASS)
       :tag("table"):addClass(TASKS_TABLE_CLASS)
       :tag("table"):addClass(TASKS_TABLE_CLASS)
Line 180: Line 180:
   div:addClass(INFOBOX_CLASS)
   div:addClass(INFOBOX_CLASS)
   add_header(div, building)
   add_header(div, building)
   add_description(div, building)
   if building.description and building.description ~= "" then
   add_subheader(div, "Tech tree prerequisite")
    add_description(div, building)
  add_tech_prerequisite(div, building)
   end
   add_subheader(div, "Construction costs")
  if building.tech_tree_previous and building.tech_tree_previous ~= "" then
  add_construction(div, building)
    add_subheader(div, "Tech tree prerequisite")
   add_subheader(div, "Work")
    add_tech_prerequisite(div, building)
  add_tasks(div, building)
   end
  if building.construction_resources and #building.construction_resources > 0 then
    add_subheader(div, "Construction costs")
    add_construction(div, building)
   end
  if building.tasks and #building.tasks > 0 then
    add_subheader(div, "Work")
    add_tasks(div, building)
  end
   return tostring(div)
   return tostring(div)
end
end
Line 197: Line 205:
---@return string wikitext
---@return string wikitext
local function append_wiki_category(wikitext, building)
local function append_wiki_category(wikitext, building)
   if not building.category or building.category == "" then return wikitext end
  wikitext = wikitext .. "\n[[Category:Buildings]]"
  return wikitext .. "\n[[Category:" .. building.category .. " Buildings]]"
   if building.category and building.category ~= "" then
    wikitext = wikitext .. "\n[[Category:" .. building.category .. " Buildings]]"
  end
  return wikitext
end
end





Latest revision as of 00:09, 11 October 2026

Documentation for this module may be created at Module:Building infobox/doc

--[[ 
Test in Scribunto console with:
=p.render({ args = { page_name = "Ore Smelter" } })
]]--
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 INFOBOX_CLASS = "bts-infobox-building"
local HEADER_CLASS = INFOBOX_CLASS .. "-header"
local HEADER_ICON_CLASS = HEADER_CLASS .. "-icon"

local TITLE_CLASS = INFOBOX_CLASS .. "-title"
local SUBTITLE_CLASS = INFOBOX_CLASS .. "-subtitle"
local SUBHEADER_CLASS = INFOBOX_CLASS .. "-subheader"

local DESCRIPTION_CLASS = INFOBOX_CLASS .. "-description"

local TECH_TREE_CLASS = INFOBOX_CLASS .. "-techtree"

local CONSTRUCTION_CLASS = INFOBOX_CLASS .. "-construction"
local CONSTRUCTION_TABLE_CLASS = CONSTRUCTION_CLASS .. "-table"

local RESOURCE_ICON_CLASS = "bts-resource-icon"

local LARGE_ICON_SIZE = "168px"
local MEDIUM_ICON_SIZE = "96px"
local SMALL_ICON_SIZE = "32px"

local TASKS_CLASS = INFOBOX_CLASS .. "-tasks"
local TASKS_TABLE_CLASS = TASKS_CLASS .. "-table"



--- Renders wikitext for the building's icon.
---@param building Building
---@return string wikitext
local function render_icon_markup(building)
  local icon_filename
  local size = LARGE_ICON_SIZE
  if building.portrait_icon then
    icon_filename = building.portrait_icon .. ".png"
  elseif building.icon then
    icon_filename = building.icon .. ".png"
    size = MEDIUM_ICON_SIZE
  else
    return ""
  end
  local image_markup = "[[File:" .. icon_filename .. "|".. size .. "|" .. building.name .. "|link=]]"
  return image_markup
end

--- Adds the header of the infobox to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param building Building
local function add_header(div, building)
  local header = div:tag("div"):addClass(HEADER_CLASS)
  header:tag("div"):addClass(TITLE_CLASS):wikitext(building.display_name)
  header:tag("div"):addClass(HEADER_ICON_CLASS):wikitext(render_icon_markup(building))
  if building.category and building.category ~= "" then
    header:tag("div"):addClass(SUBTITLE_CLASS):wikitext(building.category .. " Building")
  end
end



--- Adds the building's description to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param building Building
local function add_description(div, building)
  local inner_div = div:tag("div"):addClass(DESCRIPTION_CLASS)
  local description = building.description:gsub("<hb>", ""):gsub("</hb>", "")
  description = description:gsub("\n", "<br />")
  inner_div:wikitext(description)
  return inner_div
end



--- Adds a subheader to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param text string
local function add_subheader(div, text)
  div:tag("div"):addClass(SUBHEADER_CLASS):wikitext(text)
end



--- Adds the building's tech prerequisite to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param building Building
local function add_tech_prerequisite(div, building)
  local inner_div = div:tag("div"):addClass(TECH_TREE_CLASS)
  local check_icon = "[[File:UI teal open checkmark.png|x16px|link=]]"
  local link_markup = check_icon .. " [[" .. Building_Data_Module.get_name_by_id(building.tech_tree_previous) .. "]]"
  inner_div:tag("div"):wikitext(link_markup)
end



--- Adds an icon for a resource to the provided html table row.
---@param tr HtmlNode tr
---@param resource Resource
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 Resource
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

--- Lays out the construction resources in the provided html node.
---@param div HtmlNode enclosing infobox div
---@param building Building
local function add_construction(div, building)
  local tbl = div:tag("div"):addClass(CONSTRUCTION_CLASS)
      :tag("table"):addClass(CONSTRUCTION_TABLE_CLASS)
  for _, pair in ipairs(building.construction_resources) do
    local tr = tbl:tag("tr")
    tr:tag("td"):wikitext(pair.amount)
    local resource = Resource_Data_Module.get_resource(pair.name)
    add_resource_icon(tr, resource)
    add_resource_link(tr, resource)
  end
end



--- Lays out the building's tasks in the provided html node.
---@param div HtmlNode enclosing infobox div
---@param building Building
local function add_tasks(div, building)
  local tbl = div:tag("div"):addClass(TASKS_CLASS)
      :tag("table"):addClass(TASKS_TABLE_CLASS)
  tbl:tag("tr")
          :tag("th"):wikitext("Task"):done()
          :tag("th"):wikitext("(Time)"):done()
      :done()
  for _, task in ipairs(building.tasks) do
    local tr = tbl:tag("tr")
    tr:tag("td"):wikitext(task.task_name)
    tr:tag("td"):wikitext("(" .. task.time .. "s)")
  end
end



--- Builds the infobox wikitext and html for the given building.
---@param building Building
---@return string wikitext
local function build_infobox(building)
  ---@type HtmlNode
  local div = mw.html.create("div")
  div:addClass(INFOBOX_CLASS)
  add_header(div, building)
  if building.description and building.description ~= "" then
    add_description(div, building)
  end
  if building.tech_tree_previous and building.tech_tree_previous ~= "" then
    add_subheader(div, "Tech tree prerequisite")
    add_tech_prerequisite(div, building)
  end
  if building.construction_resources and #building.construction_resources > 0 then
    add_subheader(div, "Construction costs")
    add_construction(div, building)
  end
  if building.tasks and #building.tasks > 0 then
    add_subheader(div, "Work")
    add_tasks(div, building)
  end
  return tostring(div)
end



--- Appends the wiki category to the provided wikitext.
---@param wikitext string
---@param building Building
---@return string wikitext
local function append_wiki_category(wikitext, building)
  wikitext = wikitext .. "\n[[Category:Buildings]]"
  if building.category and building.category ~= "" then
    wikitext = wikitext .. "\n[[Category:" .. building.category .. " Buildings]]"
  end
  return wikitext
end



--#endregion



--- `#invoke` entry point. Reads `page_name` from invoke args (not the parent 
--- template); falls back to the current page title.
---@param frame table Scribunto frame from `#invoke`.
---@return string wikitext Infobox code or empty string if no building exists.
function p.render(frame)
  local args = frame.args or {}
  ---@type string
  local name = args[1] or args.page_name or mw.title.getCurrentTitle().fullText
  local building = Building_Data_Module.get_building(name)
  if not building then return "" end
  local wikitext = build_infobox(building)
  wikitext = append_wiki_category(wikitext, building)
  return wikitext
end



return p