Module:Goodbox

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

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

--- -- Constants --- local ARG_GOOD_NAME = "name" local ARG_GOOD_PURPOSE = "purpose" local ARG_GOOD_SPECIES_PREF = "species_preference"

local INDEX_GOOD_ID = 1 local INDEX_GOOD_NAME = 2 local INDEX_GOOD_DESCRIPTION = 3 local INDEX_GOOD_CATEGORY = 4 local INDEX_GOOD_EATABLE = 5 local INDEX_GOOD_CAN_BE_BURNED = 6 local INDEX_GOOD_BURNING_TIME = 7 local INDEX_GOOD_TRADING_SELL_VALUE = 8 local INDEX_GOOD_TRADING_BUY_VALUE = 9 local INDEX_GOOD_ICON_FILENAME = 10

local TITLE_ID = "ID" local TITLE_CATEGORY = "Inventory Category" local TITLE_TYPE = "ID Type" local TITLE_EATABLE = "Is eatable?" local TITLE_BURNABLE = "Is burnable?" local TITLE_BURN_TIME = "Fuel burn time" local TITLE_SELL_VALUE = "Value when sold" local TITLE_BUY_VALUE = "Price when bought"

local PATTERN_CAPTURE_BEGINNING_WITHIN_BRACKETS = "^%[(.-)%]" local PATTERN_CAPTURE_BEGINNING_AFTER_UNDERSCORE = "^_(.-)%s" local PATTERN_CAPTURE_FIRST_WORD = "^(%w-)%s" local PATTERN_FORMAT_TWO_DECIMALS = "%1.2f"

local BR = " "

local CSS_INFOBOX_INLINE_STYLE_TABLE = { ["float"] = "right", ["clear"] = "right", ["width"] = "256px", ["border"] = "1px solid #a2a9b1", ["border-spacing"] = "2px" }

--- -- Member variable: Good -- -- local good

--- -- 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 Goodbox.infobox(frame) -- Every good must have a name. local name = frame.args[ARG_GOOD_NAME] if not name or name == "" then error("You must specify the name of the good in the Goodbox template.") end -- Every Good should have a purpose. local purpose = frame.args[ARG_GOOD_PURPOSE] -- Specific parameters, may or may not be present. local speciesPref = frame.args[ARG_GOOD_SPECIES_PREF] -- Retrieve the actual data for the good. good = GoodsData.getAllDataForGood(name) if not good then return "No good found for infobox." end local goodID = good[INDEX_GOOD_ID] local goodName = good[INDEX_GOOD_NAME] local goodDescription = good[INDEX_GOOD_DESCRIPTION] local goodCategory = good[INDEX_GOOD_CATEGORY] local goodIsEatable = good[INDEX_GOOD_EATABLE] local goodIsBurnable = good[INDEX_GOOD_CAN_BE_BURNED] local goodBurnTime = good[INDEX_GOOD_BURNING_TIME] local goodSellValue = good[INDEX_GOOD_TRADING_SELL_VALUE] local goodBuyValue = good[INDEX_GOOD_TRADING_BUY_VALUE] local goodIconFilename = good[INDEX_GOOD_ICON_FILENAME] local goodType = extractType(goodID) -- Make the top of the infobox that every item has. wikiInfobox = mw.html.create("table"):css( CSS_INFOBOX_INLINE_STYLE_TABLE ) -- Title of infobox. if name then wikiInfobox:tag("tr"):tag("td"):wikitext(name):done:done:newline end -- Subtitle for category. if goodCategory then wikiInfobox:tag("tr"):tag("td"):wikitext(goodCategory):done:done:newline end -- Large icon of infobox. if goodIconFilename 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 if purpose and purpose ~= "" then innerTable:tag("tr"):tag("th"):wikitext(toTitleCase(ARG_GOOD_PURPOSE)):done :tag("td"):wikitext(purpose):done:done:newline end if speciesPref and speciesPref ~= "" then innerTable:tag("tr"):tag("th"):wikitext(toTitleCase(ARG_GOOD_SPECIES_PREF)):done :tag("td"):wikitext(speciesPref):done:done:newline end -- Data provided by the CSV if goodCategory then innerTable:tag("tr"):tag("th"):wikitext(TITLE_CATEGORY):done :tag("td"):wikitext(goodCategory):done:done:newline end -- Eatable is superfluous when the category is food. --if goodIsEatable then --	innerTable:tag("tr"):tag("th"):wikitext(TITLE_EATABLE):done --		:tag("td"):wikitext(goodIsEatable):done:done:newline --end -- Burnable is superfluous but we can use it to determine whether to show -- how long the fuel burns. -- if goodIsBurnable then -- innerTable:tag("tr"):tag("th"):wikitext(TITLE_BURNABLE):done -- :tag("td"):wikitext(goodIsBurnable):done:done:newline -- end if goodIsBurnable == "True" and goodBurnTime then innerTable:tag("tr"):tag("th"):wikitext(TITLE_BURN_TIME):done :tag("td"):wikitext(goodBurnTime):done:done:newline end if goodSellValue then innerTable:tag("tr"):tag("th"):wikitext(TITLE_SELL_VALUE):done :tag("td"):wikitext(toDecimal(goodSellValue)):done:done:newline end if goodBuyValue then innerTable:tag("tr"):tag("th"):wikitext(TITLE_BUY_VALUE):done :tag("td"):wikitext(toDecimal(goodBuyValue)):done:done:newline end if goodID then innerTable:tag("tr"):tag("th"):wikitext(TITLE_ID):done :tag("td"):wikitext("\"" .. goodID .. "\""):done:done:newline end innerTable:done wikiInfobox:done:done:newline if goodDescription then wikiInfobox:tag("tr"):tag("td"):wikitext(goodDescription):done:done:newline end return wikiInfobox end

--- -- Extracts the beginning of the ID into the type of good. For example, when -- ID = [Vessel] Pottery, the type is Vessel. -- -- @param goodID the ID of the good from the data -- @return the type of good function extractType(goodID) local typecode = goodID:match(PATTERN_CAPTURE_BEGINNING_WITHIN_BRACKETS) if not typecode then typecode = goodID:match(PATTERN_CAPTURE_BEGINNING_AFTER_UNDERSCORE) end if not typecode then typecode = goodID:match(PATTERN_CAPTURE_FIRST_WORD) end return typecode end

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

--- -- Capitalizes the first character of each word. -- -- @param title the title to capitalize -- @return the title once capitalized function toTitleCase(title) local newTitle = title:gsub("(%a)([%w_']*)", function(first, rest)			return first:upper .. rest:lower		end) newTitle, _ = newTitle:gsub("_", " ") return newTitle end

return Goodbox