Module:Shopbox

--- -- Module to create infobox for displaying on a workshop's wiki page. -- -- @module Shopbox local Shopbox = {}

--- -- Dependencies --- local RecipeData = require("Module:RecipeData")

--- -- 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 TITLE_CATEGORY = "Toolbar Category" local TITLE_SIZE = "Building Footprint" 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="

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

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

--- -- Member variable: Workshop -- local workshop

--- -- Creates an html table to display the data in a floating box. -- -- @param frame the template's calling context -- @return wiki markup for the box function Shopbox.infobox(frame) -- Every workshop must have a name. local name = frame.args[ARG_WORKSHOP_NAME] if not name or name == "" then error("You must specify the name of the building in the Shopbox template.") end -- Custom parameters -- Retrieve the actual data for the workshop. workshop = RecipeData.getAllDataForWorkshop(name) 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(""):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 = "" 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 end

--- -- Steps through the provided workplace list and counts non-empty strings -- -- @param workshopWorkplaces the list of workplaces from the workshop data -- @return the number of non-empty strings function countWorkplaces(workshopWorkplaces) local count = 0 for _, place in ipairs(workshopWorkplaces) do		if place ~= "" then count = count + 1 end end return count end

--- -- 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

--- -- Formats the information about the construction material with an icon and its -- display name -- -- @param materialID the good whose icon and name to show -- @return formatted string of wiki markup function writeConstructionMatsCellContent(materialID) local matName, matIconFilename = RecipeData.getGoodNameAndIcon(materialID) local iconMarkup = "" local linkMarkup = "" .. matName .. "" return iconMarkup .. NBSP .. linkMarkup end

function toDecimal(value) return string.format(PATTERN_FORMAT_TWO_DECIMALS, value) end

return Shopbox