<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.perfecttower2.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3AInfobox</id>
	<title>Module:Infobox - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.perfecttower2.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3AInfobox"/>
	<link rel="alternate" type="text/html" href="https://wiki.perfecttower2.com/w/index.php?title=Module:Infobox&amp;action=history"/>
	<updated>2026-10-07T14:13:53Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://wiki.perfecttower2.com/w/index.php?title=Module:Infobox&amp;diff=4188&amp;oldid=prev</id>
		<title>Speedybrain: Infobox in the TPT2 brand kit style, for Building and Infobox region</title>
		<link rel="alternate" type="text/html" href="https://wiki.perfecttower2.com/w/index.php?title=Module:Infobox&amp;diff=4188&amp;oldid=prev"/>
		<updated>2026-10-06T11:42:24Z</updated>

		<summary type="html">&lt;p&gt;Infobox in the TPT2 brand kit style, for Building and Infobox region&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Infoboxes in the style of the TPT2 brand kit (.tpt-infobox), placed beside the article by&lt;br /&gt;
-- Template:Infobox/styles.css. Used by Template:Building and Template:Infobox region.&lt;br /&gt;
-- Source: wiki repository, onwiki/Module/Infobox.lua.&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Building page names to the brand kit&amp;#039;s facility ids (game resource colors).&lt;br /&gt;
local FACILITIES = {&lt;br /&gt;
	[&amp;#039;Power Plant&amp;#039;] = &amp;#039;power-plant&amp;#039;, [&amp;#039;Mine&amp;#039;] = &amp;#039;mine&amp;#039;, [&amp;#039;Factory&amp;#039;] = &amp;#039;factory&amp;#039;,&lt;br /&gt;
	[&amp;#039;Headquarters&amp;#039;] = &amp;#039;headquarters&amp;#039;, [&amp;#039;Arcade&amp;#039;] = &amp;#039;arcade&amp;#039;, [&amp;#039;Laboratory&amp;#039;] = &amp;#039;laboratory&amp;#039;,&lt;br /&gt;
	[&amp;#039;Shipyard&amp;#039;] = &amp;#039;shipyard&amp;#039;, [&amp;#039;Trading Post&amp;#039;] = &amp;#039;trading-post&amp;#039;, [&amp;#039;Workshop&amp;#039;] = &amp;#039;workshop&amp;#039;,&lt;br /&gt;
	[&amp;#039;Museum&amp;#039;] = &amp;#039;museum&amp;#039;, [&amp;#039;Construction Firm&amp;#039;] = &amp;#039;construction-firm&amp;#039;, [&amp;#039;Statue of Cubos&amp;#039;] = &amp;#039;statue-of-cubos&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local NUMERALS = { { 10, &amp;#039;X&amp;#039; }, { 9, &amp;#039;IX&amp;#039; }, { 5, &amp;#039;V&amp;#039; }, { 4, &amp;#039;IV&amp;#039; }, { 1, &amp;#039;I&amp;#039; } }&lt;br /&gt;
&lt;br /&gt;
local function roman(n)&lt;br /&gt;
	n = tonumber(n)&lt;br /&gt;
	if not n or n &amp;lt; 1 or n &amp;gt; 39 or n % 1 ~= 0 then return nil end&lt;br /&gt;
	local out = &amp;#039;&amp;#039;&lt;br /&gt;
	for _, v in ipairs(NUMERALS) do&lt;br /&gt;
		while n &amp;gt;= v[1] do&lt;br /&gt;
			out = out .. v[2]&lt;br /&gt;
			n = n - v[1]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return out&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function value(args, key)&lt;br /&gt;
	local v = args[key]&lt;br /&gt;
	if v then&lt;br /&gt;
		v = mw.text.trim(v)&lt;br /&gt;
		if v ~= &amp;#039;&amp;#039; then return v end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function num(v)&lt;br /&gt;
	return &amp;#039;&amp;lt;span class=&amp;quot;tpt-num&amp;quot;&amp;gt;&amp;#039; .. v .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function rows(list)&lt;br /&gt;
	local dl = mw.html.create(&amp;#039;dl&amp;#039;):addClass(&amp;#039;tpt-infobox__rows&amp;#039;)&lt;br /&gt;
	for _, row in ipairs(list) do&lt;br /&gt;
		local item = dl:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
		item:tag(&amp;#039;dt&amp;#039;):wikitext(row[1])&lt;br /&gt;
		item:tag(&amp;#039;dd&amp;#039;):wikitext(row[2])&lt;br /&gt;
	end&lt;br /&gt;
	return dl&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- spec: title, label, facility (id), mark (hexagon text), image (wikitext),&lt;br /&gt;
-- rows = { { label, value }, ... }, sections = { { heading, rows }, ... }&lt;br /&gt;
function p.build(spec)&lt;br /&gt;
	local box = mw.html.create(&amp;#039;div&amp;#039;):addClass(&amp;#039;tpt-infobox&amp;#039;):addClass(&amp;#039;wiki-infobox&amp;#039;)&lt;br /&gt;
	if spec.facility then box:addClass(&amp;#039;tpt-fac-&amp;#039; .. spec.facility) end&lt;br /&gt;
	local head = box:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;tpt-infobox__head&amp;#039;)&lt;br /&gt;
	if spec.mark then&lt;br /&gt;
		head:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;tpt-hex&amp;#039;):tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;tpt-hex__mark&amp;#039;):wikitext(spec.mark)&lt;br /&gt;
	end&lt;br /&gt;
	local names = head:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
	names:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;tpt-infobox__title&amp;#039;):wikitext(spec.title)&lt;br /&gt;
	if spec.label then names:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;tpt-label&amp;#039;):wikitext(spec.label) end&lt;br /&gt;
	if spec.image then box:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;tpt-infobox__media&amp;#039;):wikitext(spec.image) end&lt;br /&gt;
	if spec.rows and #spec.rows &amp;gt; 0 then box:node(rows(spec.rows)) end&lt;br /&gt;
	for _, section in ipairs(spec.sections or {}) do&lt;br /&gt;
		box:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;tpt-infobox__section&amp;#039;):addClass(&amp;#039;tpt-label&amp;#039;):wikitext(section[1])&lt;br /&gt;
		box:node(rows(section[2]))&lt;br /&gt;
	end&lt;br /&gt;
	return box&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function styles(frame)&lt;br /&gt;
	return frame:extensionTag(&amp;#039;templatestyles&amp;#039;, &amp;#039;&amp;#039;, { src = &amp;#039;Infobox/styles.css&amp;#039; })&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function inArticle()&lt;br /&gt;
	return mw.title.getCurrentTitle().namespace == 0&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- {{Building|Tier=|ConversionRate=|Image=|Color=}}; ColorCode is no longer needed.&lt;br /&gt;
function p.building(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	local name = mw.title.getCurrentTitle().text&lt;br /&gt;
	local facility = FACILITIES[name]&lt;br /&gt;
	local tier = value(args, &amp;#039;Tier&amp;#039;)&lt;br /&gt;
	local rate = value(args, &amp;#039;ConversionRate&amp;#039;)&lt;br /&gt;
	local color = value(args, &amp;#039;Color&amp;#039;)&lt;br /&gt;
	local image = value(args, &amp;#039;Image&amp;#039;)&lt;br /&gt;
	local list = {}&lt;br /&gt;
	if tier then table.insert(list, { &amp;#039;Max. tier&amp;#039;, num(tier) }) end&lt;br /&gt;
	if rate then table.insert(list, { &amp;#039;Conversion&amp;#039;, num(rate .. &amp;#039;:1&amp;#039;) }) end&lt;br /&gt;
	if color then&lt;br /&gt;
		table.insert(list, { &amp;#039;Resource&amp;#039;, (facility and &amp;#039;&amp;lt;span class=&amp;quot;tpt-swatch&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;#039; or &amp;#039;&amp;#039;) .. color })&lt;br /&gt;
	end&lt;br /&gt;
	local box = p.build {&lt;br /&gt;
		title = name,&lt;br /&gt;
		label = &amp;#039;Town building&amp;#039;,&lt;br /&gt;
		facility = facility,&lt;br /&gt;
		mark = roman(tier),&lt;br /&gt;
		image = image and (&amp;#039;[[File:&amp;#039; .. image .. &amp;#039;|300px|alt=&amp;#039; .. name .. &amp;#039;]]&amp;#039;) or nil,&lt;br /&gt;
		rows = list,&lt;br /&gt;
	}&lt;br /&gt;
	return styles(frame) .. tostring(box) .. (inArticle() and &amp;#039;[[Category:Buildings]]&amp;#039; or &amp;#039;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- {{Infobox region|image=|lanes=|enemies=|easy=|medium=|hard=|insane=|nightmare=|impossible=}}&lt;br /&gt;
function p.region(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	local name = mw.title.getCurrentTitle().text&lt;br /&gt;
	local unknown = frame:expandTemplate { title = &amp;#039;Unknown&amp;#039; }&lt;br /&gt;
	local difficulties = {}&lt;br /&gt;
	for _, d in ipairs { { &amp;#039;easy&amp;#039;, &amp;#039;Easy&amp;#039; }, { &amp;#039;medium&amp;#039;, &amp;#039;Medium&amp;#039; }, { &amp;#039;hard&amp;#039;, &amp;#039;Hard&amp;#039; },&lt;br /&gt;
		{ &amp;#039;insane&amp;#039;, &amp;#039;Insane&amp;#039; }, { &amp;#039;nightmare&amp;#039;, &amp;#039;Nightmare&amp;#039; }, { &amp;#039;impossible&amp;#039;, &amp;#039;Impossible&amp;#039; } } do&lt;br /&gt;
		local v = value(args, d[1])&lt;br /&gt;
		table.insert(difficulties, {&lt;br /&gt;
			d[2], v and frame:expandTemplate { title = &amp;#039;Number&amp;#039;, args = { v, suffix = &amp;#039;%&amp;#039; } } or unknown,&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
	local lanes = value(args, &amp;#039;lanes&amp;#039;)&lt;br /&gt;
	local box = p.build {&lt;br /&gt;
		title = name,&lt;br /&gt;
		label = &amp;#039;Region&amp;#039;,&lt;br /&gt;
		image = &amp;#039;[[File:&amp;#039; .. (value(args, &amp;#039;image&amp;#039;) or &amp;#039;Image missing.png&amp;#039;) .. &amp;#039;|300px|alt=&amp;#039; .. name .. &amp;#039;]]&amp;#039;,&lt;br /&gt;
		rows = {&lt;br /&gt;
			{ &amp;#039;Lanes&amp;#039;, lanes and num(lanes) or unknown },&lt;br /&gt;
			{ &amp;#039;Enemies&amp;#039;, value(args, &amp;#039;enemies&amp;#039;) or unknown },&lt;br /&gt;
		},&lt;br /&gt;
		sections = { { &amp;#039;Difficulties&amp;#039;, difficulties } },&lt;br /&gt;
	}&lt;br /&gt;
	return styles(frame) .. tostring(box) .. (inArticle() and &amp;#039;[[Category:Regions]]&amp;#039; or &amp;#039;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Speedybrain</name></author>
	</entry>
</feed>