Module:Shopbox: Difference between revisions
From Against the Storm Official Wiki
(Updated to use new WorkshopsData. No longer stores external data but uses new getter methods. Improved documentation.) |
m (changed the two method calls to getAll to reflect the change in WorkshopsData) |
||
Line 169: | Line 169: | ||
local workshopStorageCap = WorkshopsData.getWorkshopStorage(workshopName) | local workshopStorageCap = WorkshopsData.getWorkshopStorage(workshopName) | ||
local workshopConstructionTime = WorkshopsData.getWorkshopConstructionTime(workshopName) | local workshopConstructionTime = WorkshopsData.getWorkshopConstructionTime(workshopName) | ||
local | local workshopWorkplaces = WorkshopsData.getWorkshopNumberOfWorkplaces(workshopName) | ||
local | local workshopRequiredGoods = WorkshopsData.getAllWorkshopRequiredGoods(workshopName) | ||
local | local workshopRecipesTable = WorkshopsData.getAllWorkshopRecipes(workshopName) | ||
-- Start the inner table | -- Start the inner table |
Revision as of 22:58, 20 November 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 WorkshopsData = require("Module:WorkshopsData") local ResourceLink = require("Module:ResourceLink") --region Private constants -- External templates local TEMPLATE_RL_ICON = "med" -- Template parameters local ARG_WORKSHOP_NAME = "name" -- Infobox header labels local TITLE_ID = "ID" local TITLE_CATEGORY = "Toolbar Category" local TITLE_SIZE = "Building Size" 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" -- Subheading for all the buildings from this template. local BUILDING_CATEGORY = "Production Building" local INDEX_REQ_STACK_SIZE = "stackSize" local INDEX_REQ_GOOD_ID = "goodID" local BOLD = "'''" local NBSP = " " local WIKIMARKUP_MED_ICON_ALT = "|32px|alt=" local CSS_INLINE_INFOBOX = { ["float"] = "right", ["clear"] = "right", ["width"] = "256px", ["border"] = "1px solid #a2a9b1", ["border-spacing"] = "3px", ["border-collapse"] = "collapse", ["margin"] = "0.5em 0 0.5em 1em" } local CSS_INLINE_INFOBOX_INNER_TABLE = { ["border-collapse"] = "collapse" } local CSS_INLINE_INFOBOX_TR_BOTTOM_DIVIDER = { ["border-bottom"] = "1px solid #a2a9b1" } local CSS_INLINE_INFOBOX_TR_TOP_DIVIDER = { ["border-top"] = "1px solid #a2a9b1" } -- Only two valid construction toolbar categories for buildings from this -- template. local ICON_FILENAMES_CATEGORIES = { ["Food Production"] = "Construct Food Production.png", ["Industry"] = "Construct Industry.png" } --endregion --region Private methods --- --- A shortcut method that redirects to ResourceLink to build links to goods --- with their IDs from the tables of required goods. --- ---@param goodID string the ID of the good to link to ---@return string wikimarkup representing an icon and link local function resourceLink(goodID) return ResourceLink.resourceLinkWithID(goodID, TEMPLATE_RL_ICON) end --- --- Lays out an inner, no-styling table to display construction goods with --- their stack sizes. --- --- @param requiredGoods table of required goods, with stack sizes and IDs --- @return string wikimarkup for a table of required goods to insert in other markup local function writeRequiredGoodsRows(requiredGoods) if not requiredGoods or #requiredGoods == 0 then error("Cannot write content with provided table of required goods.") end local requiredGoodsRows = mw.html.create("table") requiredGoodsRows:newline() for _, requiredGroup in ipairs(requiredGoods) do local stackSize = requiredGroup[INDEX_REQ_STACK_SIZE] local goodID = requiredGroup[INDEX_REQ_GOOD_ID] requiredGoodsRows:tag("tr") :tag("td"):wikitext(BOLD .. stackSize .. BOLD):done() :tag("td"):wikitext(resourceLink(goodID)):done() :done():newline() end return requiredGoodsRows end --- --- Lays out the provided recipe IDs in a small list. --- ---@param recipes table of recipe IDs ---@return string wiki markup of a list of those IDs local function writeRecipesRows(recipes) if not recipes or #recipes == 0 then error("Cannot write content with provided table of recipes.") end local recipeRows = mw.html.create("ul") recipeRows:newline() for _, recipeID in ipairs(recipes) do -- Temporarily, just write the ID of the recipe. recipeRows:tag("li"):wikitext(recipeID):done():newline() end recipeRows:done() return recipeRows 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 makeInnerTable(wikiInfobox, workshopName) -- Grab the data we'll use to populate this. local workshopID = WorkshopsData.getWorkshopID(workshopName) local workshopCategory = WorkshopsData.getWorkshopCategory(workshopName) local workshopSizeX, workshopSizeY = WorkshopsData.getWorkshopSize(workshopName) local workshopIsMovable = WorkshopsData.isWorkshopMovable(workshopName) local workshopIsEssential = WorkshopsData.isWorkshopInitiallyEssential(workshopName) local workshopStorageCap = WorkshopsData.getWorkshopStorage(workshopName) local workshopConstructionTime = WorkshopsData.getWorkshopConstructionTime(workshopName) local workshopWorkplaces = WorkshopsData.getWorkshopNumberOfWorkplaces(workshopName) local workshopRequiredGoods = WorkshopsData.getAllWorkshopRequiredGoods(workshopName) local workshopRecipesTable = WorkshopsData.getAllWorkshopRecipes(workshopName) -- Start the inner table local innerTable = wikiInfobox:tag("tr"):tag("td"):newline():tag("table"):css(CSS_INLINE_INFOBOX_INNER_TABLE) innerTable:newline() -- Additional parameters would go here. -- Construction toolbar category. if workshopCategory then local categoryIconFilename = ICON_FILENAMES_CATEGORIES[workshopCategory] if categoryIconFilename ~= nil then local categoryIconPart = "[[File:" .. categoryIconFilename .. WIKIMARKUP_MED_ICON_ALT .. workshopCategory .. "]]" innerTable:tag("tr"):css(CSS_INLINE_INFOBOX_TR_TOP_DIVIDER) :tag("th"):wikitext(TITLE_CATEGORY):done() :tag("td"):wikitext(categoryIconPart .. NBSP .. workshopCategory):done() :done():newline() end end -- Expand recipes into a small table if workshopRecipesTable and #workshopRecipesTable > 0 then local recipesRows = tostring( writeRecipesRows(workshopRecipesTable) ) innerTable:tag("tr"):css(CSS_INLINE_INFOBOX_TR_BOTTOM_DIVIDER) :tag("th"):wikitext(TITLE_RECIPES):done() :newline() :tag("td"):wikitext(recipesRows):done() :done():newline() end -- Since false is a valid value, have to directly check if it's nil. if workshopIsMovable ~= nil then innerTable:tag("tr"):css(CSS_INLINE_INFOBOX_TR_TOP_DIVIDER) :tag("th"):wikitext(TITLE_MOVABLE):done() :tag("td"):wikitext( workshopIsMovable and "Yes" or "No" ):done() :done():newline() end if workshopIsEssential ~= nil then innerTable:tag("tr"):css(CSS_INLINE_INFOBOX_TR_BOTTOM_DIVIDER) :tag("th"):wikitext(TITLE_ESSENTIAL):done() :tag("td"):wikitext( workshopIsEssential and "Yes" or "No" ):done() :done():newline() end -- Combine sizes into one line if workshopSizeX ~= nil and workshopSizeY ~= nil then innerTable:tag("tr"):css(CSS_INLINE_INFOBOX_TR_TOP_DIVIDER) :tag("th"):wikitext(TITLE_SIZE):done() :tag("td"):wikitext(workshopSizeX .. " × " .. workshopSizeY):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"):css(CSS_INLINE_INFOBOX_TR_BOTTOM_DIVIDER) :tag("th"):wikitext(TITLE_WORKPLACES):done() :tag("td"):wikitext(workshopWorkplaces):done() :done():newline() end if workshopConstructionTime then innerTable:tag("tr"):css(CSS_INLINE_INFOBOX_TR_TOP_DIVIDER) :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 workshopRequiredGoods then local requiredGoodsRows = tostring( writeRequiredGoodsRows(workshopRequiredGoods) ) innerTable:tag("tr"):css(CSS_INLINE_INFOBOX_TR_BOTTOM_DIVIDER) :tag("th"):wikitext(TITLE_CONSTRUCTION_COST):done() :newline() :tag("td"):newline():wikitext(requiredGoodsRows):newline():done() :done():newline() end if workshopID then innerTable:tag("tr"):css(CSS_INLINE_INFOBOX_TR_TOP_DIVIDER):css(CSS_INLINE_INFOBOX_TR_BOTTOM_DIVIDER) :tag("th"):wikitext(TITLE_ID):done() :tag("td"):wikitext(workshopID):done() :done():newline() end -- Close the table. innerTable:done():newline() -- Close the table cell and row the inner table is in. wikiInfobox:done():done():newline() end --endregion --region Public methods --- -- 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 workshopName = frame.args[ARG_WORKSHOP_NAME] if not workshopName or workshopName == "" then return "You must specify the name of the workshop. See [[Template:Shopbox]] for examples." end -- Use this method here to check to see whether the provided name is valid. if not WorkshopsData.getAllDataForWorkshop(workshopName) then return "Shopbox can't find the specified workshop: " .. workshopName .. "." end -- Additional template parameters would go here. -- Get the data to display. local workshopDescription = WorkshopsData.getWorkshopDescription(workshopName) local workshopIconFilename = WorkshopsData.getWorkshopIcon(workshopName) -- Make the top of the infobox that every workshop has... local wikiInfobox = mw.html.create("table"):css(CSS_INLINE_INFOBOX):newline() -- with a title... wikiInfobox:tag("tr") :tag("th"):wikitext(workshopName):done() :done():newline() -- and a subtitle, showing the functional category... wikiInfobox:tag("tr") :tag("td"):wikitext(BUILDING_CATEGORY):done() :done():newline() -- and a large icon. if workshopIconFilename then wikiInfobox:tag("tr") :tag("td"):wikitext("[[File:" .. workshopIconFilename .. "]]"):done() :done():newline() wikiInfobox:tag("tr"):css(CSS_INLINE_INFOBOX_TR_BOTTOM_DIVIDER) :tag("td"):wikitext(workshopName .. ", as seen in-game"):done() :done():newline() end makeInnerTable(wikiInfobox, workshopName) -- Finish with the flavor text. if workshopDescription then wikiInfobox:tag("tr"):css(CSS_INLINE_INFOBOX_TR_TOP_DIVIDER) :tag("td"):wikitext(workshopDescription):done() :done():newline() end return wikiInfobox end --endregion return Shopbox