Module:Resource infobox: Difference between revisions
From Beyond These Stars Official Wiki
two-row layout for Peeps benefit group |
adds generic category too |
||
| (2 intermediate revisions by the same user not shown) | |||
| Line 3: | Line 3: | ||
=mw.dumpObject(p.render( {} )) | =mw.dumpObject(p.render( {} )) | ||
=p.render({ args = { page_name = "Iron" } }) | =p.render({ args = { page_name = "Iron" } }) | ||
=p.render({ args = { page_name = "Hot Coffee" } }) | |||
]]-- | ]]-- | ||
local p = {} | local p = {} | ||
| Line 32: | Line 33: | ||
local LARGE_ICON_SIZE = "128px" | local LARGE_ICON_SIZE = "128px" | ||
local SMALL_ICON_SIZE = " | local SMALL_ICON_SIZE = "24px" | ||
| Line 41: | Line 42: | ||
local function render_icon_markup(resource) | local function render_icon_markup(resource) | ||
local icon_filename = resource.icon .. ".png" | local icon_filename = resource.icon .. ".png" | ||
local image_markup = "[[File:" .. icon_filename .. "|" .. LARGE_ICON_SIZE .. "|" .. resource.name .. "|link=]]" | local image_markup = "[[File:" .. icon_filename .. "|x" .. LARGE_ICON_SIZE .. "|" .. resource.name .. "|link=]]" | ||
return image_markup | return image_markup | ||
end | end | ||
| Line 163: | Line 164: | ||
local count = 0 | local count = 0 | ||
for _, output in ipairs(task.outputs) do | for _, output in ipairs(task.outputs) do | ||
outputs = outputs .. (count > 0 and ", " or "") .. | local name = Resource_Data_Module.get_name_by_id(output.resource) | ||
if name and name ~= "" then | |||
outputs = outputs .. (count > 0 and ", " or "") .. name | |||
count = count + 1 | |||
end | |||
end | end | ||
return outputs | return outputs | ||
| Line 177: | Line 181: | ||
local count = 0 | local count = 0 | ||
for _, input in ipairs(task.inputs) do | for _, input in ipairs(task.inputs) do | ||
inputs = inputs .. (count > 0 and ", " or "") .. | local name = Resource_Data_Module.get_name_by_id(input.resource) | ||
if name and name ~= "" then | |||
inputs = inputs .. (count > 0 and ", " or "") .. name | |||
count = count + 1 | |||
end | |||
end | end | ||
return inputs | return inputs | ||
| Line 290: | Line 297: | ||
---@return string wikitext | ---@return string wikitext | ||
local function append_wiki_category(wikitext, resource) | local function append_wiki_category(wikitext, resource) | ||
if | wikitext = wikitext .. "\n[[Category:Resources]]" | ||
if resource.category and resource.category ~= "" then | |||
wikitext = wikitext .. "\n[[Category:" .. resource.category .. " Resources]]" | |||
end | |||
return wikitext | |||
end | end | ||
Latest revision as of 00:08, 11 October 2026
Documentation for this module may be created at Module:Resource infobox/doc
--[[
Test in Scribunto console with:
=mw.dumpObject(p.render( {} ))
=p.render({ args = { page_name = "Iron" } })
=p.render({ args = { page_name = "Hot Coffee" } })
]]--
local p = {}
local Resource_Data_Module = require("Module:Resource_data")
local Building_Data_Module = require("Module:Building_data")
--#region html building helper functions
---@diagnostic disable-next-line: duplicate-doc-alias
---@alias HtmlNode table
local INFOBOX_CLASS = "bts-infobox-resource"
local HEADER_CLASS = INFOBOX_CLASS .. "-header"
local HEADER_ICON_CLASS = HEADER_CLASS .. "-icon"
local TITLE_CLASS = HEADER_CLASS .. "-title"
local SUBTITLE_CLASS = HEADER_CLASS .. "-subtitle"
local SUBHEADER_CLASS = INFOBOX_CLASS .. "-subheader"
local BENEFITS_CLASS = INFOBOX_CLASS .. "-benefits"
local BENEFITS_TABLE_CLASS = BENEFITS_CLASS .. "-table"
local PRODUCTION_CLASS = INFOBOX_CLASS .. "-production"
local PRODUCTION_TABLE_CLASS = PRODUCTION_CLASS .. "-table"
local LARGE_ICON_SIZE = "128px"
local SMALL_ICON_SIZE = "24px"
--- Renders wikitext for the resource's icon.
---@param resource Resource
---@return string wikitext
local function render_icon_markup(resource)
local icon_filename = resource.icon .. ".png"
local image_markup = "[[File:" .. icon_filename .. "|x" .. LARGE_ICON_SIZE .. "|" .. resource.name .. "|link=]]"
return image_markup
end
--- Adds the header of the infobox to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param resource Resource
local function add_header(div, resource)
local section = div:tag("div"):addClass(HEADER_CLASS)
section:tag("div"):addClass(TITLE_CLASS):wikitext(resource.display_name)
section:tag("div"):addClass(HEADER_ICON_CLASS):wikitext(render_icon_markup(resource))
if resource.category and resource.category ~= "" then
section:tag("div"):addClass(SUBTITLE_CLASS):wikitext(resource.category .. " Resource")
end
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
--- Counts the benefits to peeps for the given resource.
---@param resource Resource
---@return number
local function count_benefits(resource)
local count = 0
if resource.peep_happiness_added and resource.peep_happiness_added ~= 0 then
count = count + 1
end
if resource.peep_energy_added and resource.peep_energy_added ~= 0 then
count = count + 1
end
if resource.peep_exhaustion_removed and resource.peep_exhaustion_removed ~= 0 then
count = count + 1
end
if resource.peep_temperature_effect and resource.peep_temperature_effect ~= "" then
count = count + 1
end
return count
end
--- Adds the benefits to peeps to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param resource Resource
local function add_benefits_to_peeps(div, resource)
local section = div:tag("div"):addClass(BENEFITS_CLASS)
local count = count_benefits(resource)
if count > 0 then
local tbl = mw.html.create("table"):addClass(BENEFITS_TABLE_CLASS)
tbl:tag("tr")
:tag("th"):wikitext("Happiness"):done()
:tag("th"):wikitext("Energy"):done()
tbl:tag("tr")
:tag("td"):wikitext(resource.peep_happiness_added or 0):done()
:tag("td"):wikitext(resource.peep_energy_added or 0):done()
tbl:tag("tr")
:tag("th"):wikitext("Exhaustion"):done()
:tag("th"):wikitext("Temperature"):done()
tbl:tag("tr")
:tag("td"):wikitext(resource.peep_exhaustion_removed or 0):done()
:tag("td"):wikitext(resource.peep_temperature_effect):done()
section:node(tbl)
else
section:wikitext("None")
end
end
--- Renders the icon for a resource.
---@param resource Resource
---@return string wikitext
local function render_io_resource_icon(resource)
local icon_filename = resource.icon .. ".png"
local image_markup = "[[File:" .. icon_filename .. "|" .. SMALL_ICON_SIZE .. "|" .. resource.name .. "|link=]]"
return image_markup
end
--- Splits tasks by inputs and outputs.
---@param map_of_tasks table<string, BuildingTask[]>
---@param resource_id string the id of the resource to split tasks for
---@return table<string, BuildingTask[]> inputs
---@return table<string, BuildingTask[]> outputs
local function split_tasks_by_inputs_and_outputs(map_of_tasks, resource_id)
local inputs = {}
local outputs = {}
for building_name, tasks in pairs(map_of_tasks) do
for _, task in ipairs(tasks) do
for _, input in ipairs(task.inputs or {}) do
if input.resource == resource_id then
if not inputs[building_name] then
inputs[building_name] = {}
end
table.insert(inputs[building_name], task)
end
end
for _, output in ipairs(task.outputs or {}) do
if output.resource == resource_id then
if not outputs[building_name] then
outputs[building_name] = {}
end
table.insert(outputs[building_name], task)
end
end
end
end
return inputs, outputs
end
--- Concatenates the outputs of a task.
---@param task BuildingTask
---@return string wikitext
local function concatenate_outputs(task)
local outputs = ""
if not task.outputs or #task.outputs == 0 then return "" end
local count = 0
for _, output in ipairs(task.outputs) do
local name = Resource_Data_Module.get_name_by_id(output.resource)
if name and name ~= "" then
outputs = outputs .. (count > 0 and ", " or "") .. name
count = count + 1
end
end
return outputs
end
--- Concatenates the inputs of a task.
---@param task BuildingTask
---@return string wikitext
local function concatenate_inputs(task)
local inputs = ""
if not task.inputs or #task.inputs == 0 then return "" end
local count = 0
for _, input in ipairs(task.inputs) do
local name = Resource_Data_Module.get_name_by_id(input.resource)
if name and name ~= "" then
inputs = inputs .. (count > 0 and ", " or "") .. name
count = count + 1
end
end
return inputs
end
--- Adds the production input rows to the provided html node.
---@param tbl HtmlNode enclosing infobox div
---@param map_of_tasks_with_inputs table<string, BuildingTask[]>
---@param resource Resource
---@return number number of input rows added
local function add_production_input_rows(tbl, map_of_tasks_with_inputs, resource)
local count = 0
for building_name, tasks in pairs(map_of_tasks_with_inputs) do
for _, task in ipairs(tasks) do
local outputs = concatenate_outputs(task)
for _, input in ipairs(task.inputs) do
if input.resource == resource.name then
local building_link = "[[" .. building_name .. "]]"
local amount = input.value
local resource_icon = render_io_resource_icon(resource)
local resource_markup = amount .. "x " .. resource_icon
tbl:tag("tr")
:tag("td"):wikitext(building_link):done()
:tag("td"):wikitext(resource_markup):done()
:tag("td"):wikitext(outputs):done()
count = count + 1
end
end
end
end
return count
end
--- Adds the production output rows to the provided html node.
---@param tbl HtmlNode enclosing infobox div
---@param map_of_tasks_with_outputs table<string, BuildingTask[]>
---@param resource Resource
---@return number number of output rows added
local function add_production_output_rows(tbl, map_of_tasks_with_outputs, resource)
local count = 0
for building_name, tasks in pairs(map_of_tasks_with_outputs) do
for _, task in ipairs(tasks) do
local inputs = concatenate_inputs(task)
for _, output in ipairs(task.outputs) do
if output.resource == resource.name then
local building_link = "[[" .. building_name .. "]]"
local amount = output.value
local resource_icon = render_io_resource_icon(resource)
local resource_markup = amount .. "x " .. resource_icon
tbl:tag("tr")
:tag("td"):wikitext(building_link):done()
:tag("td"):wikitext(inputs):done()
:tag("td"):wikitext(resource_markup):done()
count = count + 1
end
end
end
end
return count
end
--- Adds the production to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param resource Resource
local function add_production(div, resource)
local section = div:tag("div"):addClass(PRODUCTION_CLASS)
local building_map_of_tasks = Building_Data_Module.get_building_names_with_tasks_including_resource(resource.name)
local map_of_tasks_with_inputs, map_of_tasks_with_outputs = split_tasks_by_inputs_and_outputs(building_map_of_tasks, resource.name)
local tbl = mw.html.create("table"):addClass(PRODUCTION_TABLE_CLASS)
tbl:tag("tr")
:tag("th"):wikitext("Building"):done()
:tag("th"):wikitext("Input"):done()
:tag("th"):wikitext("Output"):done()
local input_count = 0
local output_count = 0
if next(map_of_tasks_with_inputs) ~= nil then
input_count = add_production_input_rows(tbl, map_of_tasks_with_inputs, resource)
end
if next(map_of_tasks_with_outputs) ~= nil then
output_count = add_production_output_rows(tbl, map_of_tasks_with_outputs, resource)
end
if input_count > 0 or output_count > 0 then
section:node(tbl)
else
section:wikitext("None")
end
end
--- Builds the infobox wikitext and html for the given resource.
---@param resource Resource
---@return string wikitext
local function build_infobox(resource)
---@type HtmlNode
local div = mw.html.create("div")
div:addClass(INFOBOX_CLASS)
add_header(div, resource)
add_subheader(div, "Benefits to Peeps")
add_benefits_to_peeps(div, resource)
add_subheader(div, "In production")
add_production(div, resource)
return tostring(div)
end
--- Appends the wiki category to the provided wikitext.
---@param wikitext string
---@param resource Resource
---@return string wikitext
local function append_wiki_category(wikitext, resource)
wikitext = wikitext .. "\n[[Category:Resources]]"
if resource.category and resource.category ~= "" then
wikitext = wikitext .. "\n[[Category:" .. resource.category .. " Resources]]"
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 resource 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 resource = Resource_Data_Module.get_resource(name)
if not resource then return "" end
local wikitext = build_infobox(resource)
wikitext = append_wiki_category(wikitext, resource)
return wikitext
end
return p


