Module:GoodsData
Overview
Module for compiling goods (or resources as some call them) information from wiki data sources. Restructures the flat data tables that are produced from CsvUtils to make them more conducive to Lua methods that need to display the information.
Usage
The standard way of using this module is a call like the following:
iconFilename = GoodsData.getGoodIcon(goodName)
This will return a string corresponding to the filename of the good, including the .png extension. It is preferable to call the getter methods with the name of the good rather than retrieving the entire record for the good, so that your code stays protected from any variations in this module. The getter methods are all called with the plain-language name of the good, as spelled in the game.
longDescription = GoodsData.getGoodDescription(goodName) inventoryCategory = GoodsData.getGoodCategory(goodName) isEatable = GoodsData.isGoodEatable(goodName) isBurnable = GoodsData.isGoodBurnable(goodName) burnSeconds = GoodsData.getGoodBurnTime(goodName) amberSellValue, amberBuyValue = GoodsData.getGoodValue(goodName) iconFilename = GoodsData.getGoodIcon(goodName)
As a last resort, or if you need to transform the data structure, you can
call the method getAllDataForGood(displayName). This returns a whole record
from the data table corresponding to the requested display name.
The data table for goods has the following structure:
goodsTable = {
["good1_ID"] = {
["id"] = "good1_ID",
["displayName"] = "Plain Language Name",
["description"] = "A long string with some HTML entities too.",
["category"] = "Inventory category",
["eatable"] = true or false if food
["canBeBurned"] = true or false if fuel and sacrifice
["burningTime"] = 99, number of seconds
["tradingSellValue"] = 99.99, in amber
["tradingBuyValue"] = 99.99, in amber
["iconName"] = "Icon_Resource_filename.png" including PNG extension
},
["good2_ID"] = {
...
},
["good3_ID"] = {
...
},
...
}
---
-- Module for compiling goods (or resources as some call them) information from
-- wiki data sources.
--
-- @module GoodsData
local GoodsData = {}
---
-- Dependencies
---
local CsvUtils = require("Module:CsvUtils")
---
-- Constants for this module
---
local GOODS_DATA_TEMPLATE_NAME = "Template:Goods_csv"
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 HEADER_ROW = 1
local DATA_ROWS = 2
---
-- Private member variables
---
-- Main data tables. Populated from CSV data and organized better for Lua.
-- like this: table[goodID] = table containing good data
local goodsTable
-- Lookup maps. Built once and reused on subsequent calls
-- like this: table[display name] = goodID
local goodsNameToGoodID
---
-- Data loader function. Calls the data templates, restructures the data to be
-- useful for getter methods, and makes a merge table.
--
-- This method is called the first time any of the actual template methods are
-- invoked and they see that the data tables are nil. This method populates
-- them and reorganizes them for easier use (and easier code).
function loadData()
-- Use the CSV utility module to load the data templates we need for
-- resources.
local originalGoodsTable, goodsHeaderLookup = CsvUtils.luaTableFromCSV(CsvUtils.extractCSV(GOODS_DATA_TEMPLATE_NAME))
-- Now restructure the table so subtables can be passed to member functions
-- for cleaner code.
goodsTable = restructureGoodsTable(originalGoodsTable, goodsHeaderLookup)
end
---
-- Retrieve all data for the specified good.
--
-- @param goodName plain language name of the good
-- @return a table containing the data for the specified good
function GoodsData.getAllDataForGood(goodName)
if not goodsTable then
loadData()
end
local targetGoodID = findGoodIDByName(goodName)
if not targetGoodID then
error("No good found. Please check spelling and any punctuation like an apostrophe: " .. goodName)
end
return goodsTable[targetGoodID]
end
---
-- Since the goods information is already flat and well structured, all this has
-- to do is swap out the integer keys for the good IDs and only return the data
-- rows, without the header row.
--
-- @param oldGoodsTable the CSV-based table, with a header row then data rows
-- @param goodsHeaderLookup the lookup table built from the CSV data
-- @return a new table for use in looking up goods data
function restructureGoodsTable(oldGoodsTable, goodsHeaderLookup)
local newGoodsTable = {}
for _, good in ipairs(oldGoodsTable[DATA_ROWS]) do
newGoodsTable[good[INDEX_GOOD_ID]] = good
end
return newGoodsTable
end
---
-- Look up so products and ingredients can be found by their common id, rather
-- than their display name, which people are more familiar with.
--
-- Uses the display name provided to look up the associated ID for the good.
-- Builds a lookup table the first time it's called so it only has to happen
-- once.
--
-- @param displayName the plain-language name of the good to find
-- @return the ID of the good found, or nil if not found
function findGoodIDByName(displayName)
if not goodsTable then
loadData()
end
local foundGoodID = nil
-- Decide whether we need to traverse the big table. If this isn't the first
-- time this method is called, we won't have to build the table again, we
-- can just look it up.
if not goodsNameToGoodID then
goodsNameToGoodID = {}
for goodID, good in pairs(goodsTable) do
if not foundGoodID and good[INDEX_GOOD_NAME] == displayName then
-- Found it, keep traversing to build the rest of the map.
foundGoodID = goodID
end
goodsNameToGoodID[good[INDEX_GOOD_NAME]] = goodID
end
else
-- From the lookup table.
foundGoodID = goodsNameToGoodID[displayName]
end
return foundGoodID
end
---
-- Retrieves the name and icon filename for a good.
--
-- @param goodID the ID of the good to look up
-- @return display name, icon filename
function GoodsData.getGoodNameAndIcon(goodID)
if not recipeTable or not workshopTable or not goodsTable then
loadData()
end
local good = goodsTable[goodID]
if not good then
error("ID for good not found to look up name and icon: " .. goodID)
end
return good[INDEX_GOOD_NAME], good[INDEX_GOOD_ICON_FILENAME]
end
return GoodsData


