Module:Shopbox: Difference between revisions

From Against the Storm Official Wiki
(fixing typos)
m (changed category icon maker)
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
---
---
-- Module to create infobox for displaying on a workshop's wiki page.
--- Module to create an infobox for displaying on a workshop's wiki page.
--
---
-- @module Shopbox
--- Shows the facts from the data about the specified workshop in an easy-to-
local Shopbox = {}
--- read table, with a large icon, information, categories, and the flavor
 
--- text.
---
---
-- Dependencies
--- This should be invoked from Template:Shopbox with the parameter of the
--- workshop whose infobox should be shown. See the template documentation for
--- more information about parameters and errors and to see examples.
---
---
local RecipeData = require("Module:RecipeData")
--- @module Shopbox
local Shopbox = {}


---
-- Constants
---
local ARG_WORKSHOP_NAME = "name"


local INDEX_WORKSHOP_ID = 1
local INDEX_WORKSHOP_NAME = 2
local INDEX_WORKSHOP_DESCRIPTION = 3
local INDEX_WORKSHOP_CATEGORY = 4
local INDEX_WORKSHOP_SIZE_X = 5
local INDEX_WORKSHOP_SIZE_Y = 6
local INDEX_WORKSHOP_CITY_SCORE = 7
local INDEX_WORKSHOP_MOVABLE = 8
local INDEX_WORKSHOP_INITIALLY_ESSENTIAL = 9
local INDEX_WORKSHOP_STORAGE = 10
local INDEX_WORKSHOP_CONSTRUCTION_TIME = 11
local INDEX_WORKSHOP_REQUIRED_GOODS = 12
local INDEX_WORKSHOP_WORKPLACES = 13
local INDEX_WORKSHOP_RECIPES = 14


local TITLE_ID = "ID"
local Infobox = require("Module:Infobox")
local TITLE_CATEGORY = "Toolbar Category"
local WorkshopsData = require("Module:WorkshopsData")
local TITLE_SIZE = "Building Footprint"
local StyleUtils = require("Module:StyleUtils")
local TITLE_MOVABLE = "Movable"
local TITLE_ESSENTIAL = "Initially Essential"
local TITLE_STORAGE_CAPACITY = "Storage Capacity"
local TITLE_CONSTRUCTION_TIME = "Construction Time"
local TITLE_CONSTRUCTION_COST = "Construction Cost"
local TITLE_WORKPLACES = "Workplaces"
local TITLE_RECIPES = "Recipes"


local VALUE_TYPE = "Production Building"


local BOLD = "'''"
local NBSP = " "


local WIKI_MED_ICON_MARKUP = "|32px|alt="
--region Private constants


local categoryIcons = {
local ARGS = {
["Food Production"] = "Construct Food Production.png",
["name"] = "name",
["Industry"] = "Construct Industry.png"
}
}


local CSS_INFOBOX_INLINE_STYLE_TABLE = {
--endregion
["float"] = "right",
 
["clear"] = "right",
["width"] = "256px",
["border"] = "1px solid #a2a9b1",
["border-spacing"] = "3px",
["margin"] = "0.5em 0 0.5em 1em"
}




--region Private methods


---
---
-- Member variable: Workshop
--- Shortcut method to expand a template with parameters
--  
---
local workshop
---@param workshopName string the name of the workshop
---@return string html markup returned by the template
local function expandRecipeList(workshopName)
 
return mw.getCurrentFrame():expandTemplate{ title="Recipe", args={
building=workshopName, display="list" } }
end






---
---
-- Creates an html table to display the data in a floating box.
--- Builds using the provided wikiInfobox a few header items.
--
---
-- @param frame the template's calling context
---@param wikiInfobox table mw.html object into which we're building this
-- @return wiki markup for the box
---@param workshopName string the name of the building the infobox is about
function Shopbox.infobox(frame)
---@return table the Mediawiki html object into which we've been adding things
local function makeHeaderContent(wikiInfobox, workshopName)
-- Every workshop must have a name.
 
local name = frame.args[ARG_WORKSHOP_NAME]
-- Grab the data we'll use to populate this.
local workshopDescription = WorkshopsData.getWorkshopDescription(workshopName)
if not name or name == "" then
local workshopIconFilename = WorkshopsData.getWorkshopIcon(workshopName)
error("You must specify the name of the building in the Shopbox template.")
 
end
-- Start the header area
local header = Infobox.startNewHeader(wikiInfobox)
-- Custom parameters
 
Infobox.makeTitle(header, workshopName)
-- Retrieve the actual data for the workshop.
Infobox.makeFlavorText(header, workshopDescription)
workshop = RecipeData.getAllDataForWorkshop(name)
Infobox.makeTitleIcon(header, workshopIconFilename)
 
if not workshop then
return "No building found for infobox."
end
local workshopID = workshop[INDEX_WORKSHOP_ID]
local workshopDescription = workshop[INDEX_WORKSHOP_DESCRIPTION]
local workshopCategory = workshop[INDEX_WORKSHOP_CATEGORY]
local workshopSizeX = workshop[INDEX_WORKSHOP_SIZE_X]
local workshopSizeY = workshop[INDEX_WORKSHOP_SIZE_Y]
local workshopIsMovable = workshop[INDEX_WORKSHOP_MOVABLE]
local workshopIsEssential = workshop[INDEX_WORKSHOP_INITIALLY_ESSENTIAL]
local workshopStorageCap = workshop[INDEX_WORKSHOP_STORAGE]
local workshopConstructionTime = workshop[INDEX_WORKSHOP_CONSTRUCTION_TIME]
local workshopConstructionGoods = workshop[INDEX_WORKSHOP_REQUIRED_GOODS]
local workshopWorkplaces = workshop[INDEX_WORKSHOP_WORKPLACES]
local workshopRecipes = workshop[INDEX_WORKSHOP_RECIPES]
local _, workshopIconFilename = RecipeData.getWorkshopNameAndIcon(workshopID)
-- Make the top of the infobox that every item has.
wikiInfobox = mw.html.create("table"):css( CSS_INFOBOX_INLINE_STYLE_TABLE ):newline()
-- Title of infobox.
if name then
wikiInfobox:tag("tr"):tag("td"):wikitext(name):done():done():newline()
end
-- Subtitle for category.
wikiInfobox:tag("tr"):tag("td"):wikitext(VALUE_TYPE):done():done():newline()
-- Large icon of infobox.
if workshopIconFilename then
wikiInfobox:tag("tr"):tag("td"):wikitext("[[File:" .. workshopIconFilename .. ".png]]"):done():done():newline()
wikiInfobox:tag("tr"):tag("td"):wikitext(name .. " icon as seen in-game"):done():done():newline()
end
-- Data fields of the infobox with labels and values
local innerTable = wikiInfobox:tag("tr"):tag("td"):tag("table")
innerTable:newline()
-- Data provided by the CSV
if workshopCategory then
local catIcon = "[[File:" .. categoryIcons[workshopCategory] .. WIKI_MED_ICON_MARKUP .. workshopCategory .. "]]"
innerTable:tag("tr"):tag("th"):wikitext(TITLE_CATEGORY):done()
:tag("td"):wikitext(catIcon .. NBSP .. workshopCategory):done():done():newline()
end
if workshopSizeX and workshopSizeY then
innerTable:tag("tr"):tag("th"):wikitext(TITLE_SIZE):done()
:tag("td"):wikitext(workshopSizeX .. " × " .. workshopSizeY):done():done():newline()
end
if workshopIsMovable then
local isMovable = workshopIsMovable == "TRUE"
innerTable:tag("tr"):tag("th"):wikitext(TITLE_MOVABLE):done()
:tag("td"):wikitext( isMovable and "Yes" or "No" ):done():done():newline()
end
if workshopIsEssential then
local isEssential = workshopIsEssential == "TRUE"
innerTable:tag("tr"):tag("th"):wikitext(TITLE_ESSENTIAL):done()
:tag("td"):wikitext( isEssential and "Yes" or "No" ):done():done():newline()
end
if workshopStorageCap then
innerTable:tag("tr"):tag("th"):wikitext(TITLE_STORAGE_CAPACITY):done()
:tag("td"):wikitext(workshopStorageCap):done():done():newline()
end
if workshopWorkplaces then
innerTable:tag("tr"):tag("th"):wikitext(TITLE_WORKPLACES):done()
:tag("td"):wikitext(countWorkplaces(workshopWorkplaces)):done():done():newline()
end
if workshopConstructionTime then
innerTable:tag("tr"):tag("th"):wikitext(TITLE_CONSTRUCTION_TIME):done()
:tag("td"):wikitext(workshopConstructionTime):done():done():newline()
end
-- Need to build a separate table to display building materials
if workshopConstructionGoods then
local matsTable = tostring(writeRequiredGoodsRows(workshopConstructionGoods))
innerTable:tag("tr"):tag("th"):wikitext(TITLE_CONSTRUCTION_COST):done()
:newline()
:tag("td"):newline():wikitext(matsTable):newline():done():done():newline()
end
wikiInfobox:newline()
if workshopDescription then
wikiInfobox:tag("tr"):tag("td"):wikitext(workshopDescription):done():done():newline()
end
return wikiInfobox
return wikiInfobox
end
end
Line 183: Line 71:


---
---
-- Steps through the provided workplace list and counts non-empty strings
--- Builds using the provided wikiInfobox a subtable to lay out headers and
--
--- fields.
-- @param workshopWorkplaces the list of workplaces from the workshop data
---
-- @return the number of non-empty strings
---@param wikiInfobox table mw.html object into which we're building this
function countWorkplaces(workshopWorkplaces)
---@param workshopName string the name of the good the infobox is about
---@return table the Mediawiki html object into which we've been adding things
local count = 0
local function makeInnerContent(wikiInfobox, workshopName)
 
for _, place in ipairs(workshopWorkplaces) do
-- Grab the data we'll use to populate this.
if place ~= "" then
local workshopCategory = WorkshopsData.getWorkshopCategory(workshopName)
count = count + 1
local workshopRecipesTable = WorkshopsData.getAllWorkshopRecipes(workshopName)
end
local workshopIsMovable = WorkshopsData.isWorkshopMovable(workshopName)
end
local workshopIsEssential = WorkshopsData.isWorkshopInitiallyEssential(workshopName)
local workshopSizeX, workshopSizeY = WorkshopsData.getWorkshopSize(workshopName)
return count
local workshopStorageCap = WorkshopsData.getWorkshopStorage(workshopName)
end
local workshopWorkplaces = WorkshopsData.getWorkshopNumberOfWorkplaces(workshopName)
local workshopConstructionTime = WorkshopsData.getWorkshopConstructionTime(workshopName)
local workshopRequiredGoods = WorkshopsData.getAllWorkshopRequiredGoods(workshopName)
local workshopID = WorkshopsData.getWorkshopID(workshopName)
 
-- Start the inner table
local innerTable = Infobox.startNewInnerTable(wikiInfobox)
 
-- we'll reuse this to mark where separators are needed in the table
local needsSeparator = false
 
-- Additional parameters would go here.
 
needsSeparator = Infobox.makeInnerRow(innerTable, workshopCategory, needsSeparator,
Infobox.TITLE_CATEGORY,
Infobox.makeCategoryIcon(workshopCategory, false) .. StyleUtils.NBSP .. workshopCategory)
needsSeparator = Infobox.makeInnerRow(innerTable, workshopRecipesTable and #workshopRecipesTable > 0,
needsSeparator, Infobox.TITLE_RECIPES,
expandRecipeList(workshopName))
 
needsSeparator = true
 
needsSeparator = Infobox.makeInnerRow(innerTable, workshopIsMovable, needsSeparator,
Infobox.TITLE_MOVABLE, workshopIsMovable and "Yes" or "No")
needsSeparator = Infobox.makeInnerRow(innerTable, workshopIsEssential, needsSeparator,
Infobox.TITLE_ESSENTIAL, workshopIsEssential and "Yes" or "No")
needsSeparator = Infobox.makeInnerRow(innerTable, workshopSizeX and workshopSizeY,
needsSeparator, Infobox.TITLE_SIZE, workshopSizeX .. " × " .. workshopSizeY)
needsSeparator = Infobox.makeInnerRow(innerTable, workshopStorageCap, needsSeparator,
Infobox.TITLE_STORAGE_CAPACITY, workshopStorageCap)
needsSeparator = Infobox.makeInnerRow(innerTable, workshopWorkplaces, needsSeparator,
Infobox.TITLE_WORKPLACES, workshopWorkplaces)
 
needsSeparator = true
 
needsSeparator = Infobox.makeInnerRow(innerTable, workshopConstructionTime,
needsSeparator, Infobox.TITLE_CONSTRUCTION_TIME,
workshopConstructionTime)
needsSeparator = Infobox.makeInnerRow(innerTable, workshopRequiredGoods, needsSeparator,
Infobox.TITLE_CONSTRUCTION_COST,
Infobox.writeRequiredGoodsRows(workshopRequiredGoods) )
 
needsSeparator = true


needsSeparator = Infobox.makeInnerRow(innerTable, workshopID, needsSeparator,
Infobox.TITLE_ID, StyleUtils.ITALIC .. workshopID .. StyleUtils.ITALIC)


-- Close the inner table, and return it with the passed context
Infobox.endInnerTable(wikiInfobox, innerTable)


---
return wikiInfobox
-- Lays out an inner, no-styling table to display construction goods.
--
-- @param
function writeRequiredGoodsRows(requiredGoods)
local matsTable =  mw.html.create("table")
matsTable:newline()
for _, matsGroup in ipairs(requiredGoods) do
-- Skip empty groups
if #matsGroup > 0 then
local stackSize = matsGroup[1]
local materialID = matsGroup[2]
matsTable:tag("tr")
:tag("td"):wikitext(BOLD .. stackSize .. BOLD):done()
:tag("td"):wikitext(writeConstructionMatsCellContent(materialID)):done()
:done():newline()
end
end
return matsTable
end
end


--endregion


--region Public methods


---
---
-- Formats the information about the construction material with an icon and its
--- Creates an html and wiki markup to display the data in an infobox.
-- display name
---
--
--- @param frame table from template's calling context
-- @param materialID the good whose icon and name to show
--- @return string of html and wiki markup
-- @return formatted string of wiki markup
function Shopbox.renderShopbox(frame)
function writeConstructionMatsCellContent(materialID)
local matName, matIconFilename = RecipeData.getGoodNameAndIcon(materialID)
-- Every workshop must have a name.
local workshopName = frame.args[ARGS.name]
local iconMarkup = "[[File:" .. matIconFilename .. ".png" .. WIKI_MED_ICON_MARKUP .. matName .. "|link=" .. matName .. "]]"
if not workshopName or workshopName == "" then
local linkMarkup = "[[" .. matName .. "]]"
return "You must specify the name of the building. See [[Template:Shopbox]] for examples."
end
return iconMarkup .. NBSP .. linkMarkup
end


-- Use this method here to check to see whether the provided name is valid.
if not WorkshopsData.getWorkshopID(workshopName) then
return "Shopbox can't find the specified building: " .. workshopName .. "."
end


-- Additional template parameters would go here.


function toDecimal(value)
local wikiInfobox = Infobox.startNewInfobox()
makeHeaderContent(wikiInfobox, workshopName)
makeInnerContent(wikiInfobox, workshopName)
return string.format(PATTERN_FORMAT_TWO_DECIMALS, value)
return wikiInfobox
end
end


 
--endregion


return Shopbox
return Shopbox

Latest revision as of 05:46, 24 December 2023

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

---
--- Module to create an infobox for displaying on a workshop's wiki page.
---
--- Shows the facts from the data about the specified workshop in an easy-to-
--- read table, with a large icon, information, categories, and the flavor
--- text.
---
--- This should be invoked from Template:Shopbox with the parameter of the
--- workshop whose infobox should be shown. See the template documentation for
--- more information about parameters and errors and to see examples.
---
--- @module Shopbox
local Shopbox = {}



local Infobox = require("Module:Infobox")
local WorkshopsData = require("Module:WorkshopsData")
local StyleUtils = require("Module:StyleUtils")



--region Private constants

local ARGS = {
	["name"] = "name",
}

--endregion



--region Private methods

---
--- Shortcut method to expand a template with parameters
---
---@param workshopName string the name of the workshop
---@return string html markup returned by the template
local function expandRecipeList(workshopName)

	return mw.getCurrentFrame():expandTemplate{ title="Recipe", args={
		building=workshopName, display="list"	} }
end



---
--- Builds using the provided wikiInfobox a few header items.
---
---@param wikiInfobox table mw.html object into which we're building this
---@param workshopName string the name of the building the infobox is about
---@return table the Mediawiki html object into which we've been adding things
local function makeHeaderContent(wikiInfobox, workshopName)

	-- Grab the data we'll use to populate this.
	local workshopDescription = WorkshopsData.getWorkshopDescription(workshopName)
	local workshopIconFilename = WorkshopsData.getWorkshopIcon(workshopName)

	-- Start the header area
	local header = Infobox.startNewHeader(wikiInfobox)

	Infobox.makeTitle(header, workshopName)
	Infobox.makeFlavorText(header, workshopDescription)
	Infobox.makeTitleIcon(header, workshopIconFilename)

	return wikiInfobox
end



---
--- Builds using the provided wikiInfobox a subtable to lay out headers and
--- fields.
---
---@param wikiInfobox table mw.html object into which we're building this
---@param workshopName string the name of the good the infobox is about
---@return table the Mediawiki html object into which we've been adding things
local function makeInnerContent(wikiInfobox, workshopName)

	-- Grab the data we'll use to populate this.
	local workshopCategory = WorkshopsData.getWorkshopCategory(workshopName)
	local workshopRecipesTable = WorkshopsData.getAllWorkshopRecipes(workshopName)
	local workshopIsMovable = WorkshopsData.isWorkshopMovable(workshopName)
	local workshopIsEssential = WorkshopsData.isWorkshopInitiallyEssential(workshopName)
	local workshopSizeX, workshopSizeY = WorkshopsData.getWorkshopSize(workshopName)
	local workshopStorageCap = WorkshopsData.getWorkshopStorage(workshopName)
	local workshopWorkplaces = WorkshopsData.getWorkshopNumberOfWorkplaces(workshopName)
	local workshopConstructionTime = WorkshopsData.getWorkshopConstructionTime(workshopName)
	local workshopRequiredGoods = WorkshopsData.getAllWorkshopRequiredGoods(workshopName)
	local workshopID = WorkshopsData.getWorkshopID(workshopName)

	-- Start the inner table
	local innerTable = Infobox.startNewInnerTable(wikiInfobox)

	-- we'll reuse this to mark where separators are needed in the table
	local needsSeparator = false

	-- Additional parameters would go here.

	needsSeparator = Infobox.makeInnerRow(innerTable, workshopCategory, needsSeparator,
			Infobox.TITLE_CATEGORY,
			Infobox.makeCategoryIcon(workshopCategory, false) .. StyleUtils.NBSP .. workshopCategory)
	needsSeparator = Infobox.makeInnerRow(innerTable, workshopRecipesTable and #workshopRecipesTable > 0,
			needsSeparator, Infobox.TITLE_RECIPES,
			expandRecipeList(workshopName))

	needsSeparator = true

	needsSeparator = Infobox.makeInnerRow(innerTable, workshopIsMovable, needsSeparator,
			Infobox.TITLE_MOVABLE, workshopIsMovable and "Yes" or "No")
	needsSeparator = Infobox.makeInnerRow(innerTable, workshopIsEssential, needsSeparator,
			Infobox.TITLE_ESSENTIAL, workshopIsEssential and "Yes" or "No")
	needsSeparator = Infobox.makeInnerRow(innerTable, workshopSizeX and workshopSizeY,
			needsSeparator, Infobox.TITLE_SIZE, workshopSizeX .. " × " .. workshopSizeY)
	needsSeparator = Infobox.makeInnerRow(innerTable, workshopStorageCap, needsSeparator,
			Infobox.TITLE_STORAGE_CAPACITY, workshopStorageCap)
	needsSeparator = Infobox.makeInnerRow(innerTable, workshopWorkplaces, needsSeparator,
			Infobox.TITLE_WORKPLACES, workshopWorkplaces)

	needsSeparator = true

	needsSeparator = Infobox.makeInnerRow(innerTable, workshopConstructionTime,
			needsSeparator, Infobox.TITLE_CONSTRUCTION_TIME,
			workshopConstructionTime)
	needsSeparator = Infobox.makeInnerRow(innerTable, workshopRequiredGoods, needsSeparator,
			Infobox.TITLE_CONSTRUCTION_COST,
			Infobox.writeRequiredGoodsRows(workshopRequiredGoods) )

	needsSeparator = true

	needsSeparator = Infobox.makeInnerRow(innerTable, workshopID, needsSeparator,
			Infobox.TITLE_ID, StyleUtils.ITALIC .. workshopID .. StyleUtils.ITALIC)

	-- Close the inner table, and return it with the passed context
	Infobox.endInnerTable(wikiInfobox, innerTable)

	return wikiInfobox
end

--endregion



--region Public methods

---
--- Creates an html and wiki markup to display the data in an infobox.
---
--- @param frame table from template's calling context
--- @return string of html and wiki markup
function Shopbox.renderShopbox(frame)
	
	-- Every workshop must have a name.
	local workshopName = frame.args[ARGS.name]
	if not workshopName or workshopName == "" then
		return "You must specify the name of the building. See [[Template:Shopbox]] for examples."
	end

	-- Use this method here to check to see whether the provided name is valid.
	if not WorkshopsData.getWorkshopID(workshopName) then
		return "Shopbox can't find the specified building: " .. workshopName .. "."
	end

	-- Additional template parameters would go here.

	local wikiInfobox = Infobox.startNewInfobox()
	makeHeaderContent(wikiInfobox, workshopName)
	makeInnerContent(wikiInfobox, workshopName)
	
	return wikiInfobox
end

--endregion

return Shopbox