Module:InstitutionsData: Difference between revisions
From Against the Storm Official Wiki
m (mistake in comment) |
(Added method to look up all institutions with a given recipe ID (service ID)) |
||
Line 107: | Line 107: | ||
--- like this: table[display name] = institutionID | --- like this: table[display name] = institutionID | ||
local mapNamesToIDs | local mapNamesToIDs | ||
--- Lookup map. Built once and reused on all subsequent calls within this | |||
--- session, like this: table[recipeID] = { institutionName1, | |||
--- institutionName2, ... } | |||
local mapRecipeIDsToInstitutionNames | |||
--endregion | --endregion | ||
Line 214: | Line 218: | ||
--- institution. | --- institution. | ||
--- | --- | ||
--- @param institutionName string the name of the institution | |||
--- @param originalInstitution table institution data record from which to make subtable | --- @param originalInstitution table institution data record from which to make subtable | ||
--- @param institutionsHeaderLookup table header lookup built from the CSV data | --- @param institutionsHeaderLookup table header lookup built from the CSV data | ||
--- @return table subtable with the recipe IDs | --- @return table subtable with the recipe IDs | ||
local function makeRecipesSubtable(originalInstitution, institutionsHeaderLookup) | local function makeRecipesSubtable(institutionName, originalInstitution, institutionsHeaderLookup) | ||
-- A constant we'll need only within this function. | -- A constant we'll need only within this function. | ||
Line 239: | Line 244: | ||
(recipe4 ~= "" and recipe4) or nil | (recipe4 ~= "" and recipe4) or nil | ||
} | } | ||
-- Make reverse-lookup map. | |||
if recipe1 and recipe1 ~= "" then | |||
if not mapRecipeIDsToInstitutionNames[recipe1] then | |||
mapRecipeIDsToInstitutionNames[recipe1] = {} | |||
end | |||
table.insert( mapRecipeIDsToInstitutionNames[recipe1], institutionName) | |||
end | |||
if recipe2 and recipe2 ~= "" then | |||
if not mapRecipeIDsToInstitutionNames[recipe2] then | |||
mapRecipeIDsToInstitutionNames[recipe2] = {} | |||
end | |||
table.insert( mapRecipeIDsToInstitutionNames[recipe2], institutionName) | |||
end | |||
if recipe3 and recipe3 ~= "" then | |||
if not mapRecipeIDsToInstitutionNames[recipe3] then | |||
mapRecipeIDsToInstitutionNames[recipe3] = {} | |||
end | |||
table.insert( mapRecipeIDsToInstitutionNames[recipe3], institutionName) | |||
end | |||
if recipe4 and recipe4 ~= "" then | |||
if not mapRecipeIDsToInstitutionNames[recipe4] then | |||
mapRecipeIDsToInstitutionNames[recipe4] = {} | |||
end | |||
table.insert( mapRecipeIDsToInstitutionNames[recipe4], institutionName) | |||
end | |||
return recipes | return recipes | ||
Line 271: | Line 302: | ||
mapNamesToIDs = {} | mapNamesToIDs = {} | ||
mapRecipeIDsToInstitutionNames = {} | |||
local newInstitutionsTable = {} | local newInstitutionsTable = {} | ||
Line 290: | Line 322: | ||
newInstitution[INDEX_REQUIRED_GOODS] = makeRequiredGoodsSubtable(originalInstitution, institutionsHeaderLookup) | newInstitution[INDEX_REQUIRED_GOODS] = makeRequiredGoodsSubtable(originalInstitution, institutionsHeaderLookup) | ||
newInstitution[INDEX_WORKPLACES] = makeWorkplacesSubtable(originalInstitution, institutionsHeaderLookup) | newInstitution[INDEX_WORKPLACES] = makeWorkplacesSubtable(originalInstitution, institutionsHeaderLookup) | ||
newInstitution[INDEX_RECIPES] = makeRecipesSubtable(originalInstitution, institutionsHeaderLookup) | newInstitution[INDEX_RECIPES] = makeRecipesSubtable(newInstitution[INDEX_NAME], originalInstitution, institutionsHeaderLookup) | ||
newInstitutionsTable[ newInstitution[INDEX_ID] ] = newInstitution | newInstitutionsTable[ newInstitution[INDEX_ID] ] = newInstitution | ||
Line 787: | Line 819: | ||
return nil | return nil | ||
end | end | ||
end | |||
--- | |||
--- Retrieve all display names of institutions that have the specified recipe | |||
--- ID. | |||
--- | |||
---@param recipeID string the ID of the recipe | |||
---@return table of institution names that produce the specified recipe | |||
function InstitutionsData.getInstitutionNamesWithRecipeID(recipeID) | |||
-- At runtime, this should never be nil or empty. | |||
if not recipeID or recipeID == "" then | |||
error("Parameter is nil or empty for product ID.") | |||
end | |||
if not institutionsTable then | |||
loadData() | |||
end | |||
return mapRecipeIDsToInstitutionNames[recipeID] | |||
end | end | ||
Revision as of 03:19, 26 November 2023
Documentation for this module may be created at Module:InstitutionsData/doc
--- --- Module for compiling service-buildings 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. ---- --- The standard way of using this module is a call like the following: --- --- sizeX, sizeY = InstitutionsData.getInstitutionSize(institutionName) --- --- This will return the 2 x 2 size of the institution. It is preferable to --- call the getter methods with the name of the institution rather than --- retrieving the entire data record for the institution. This way your code --- stays protected from variations in this module. These getter methods are --- called with the plain-language display name of the institution, as spelled --- in the game, including punctuation. --- --- * longDescription = InstitutionsData.getInstitutionDescription(institutionName) --- * constructionCategory = InstitutionsData.getInstitutionCategory(institutionName) --- * sizeX, sizeY = InstitutionsData.getInstitutionSize(institutionName) --- * requiredGoodID, stackSize = InstitutionsData.getInstitutionRequiredGood(institutionName, requirementIndex) --- * timeSeconds = InstitutionsData.getInstitutionConstructionTime(institutionName) --- * cityScore = InstitutionsData.getInstitutionCityScore(institutionName) --- * isMovable = InstitutionsData.isInstitutionMovable(institutionName) --- * isInitiallyEssential = InstitutionsData.isInstitutionInitiallyEssential(institutionName) --- * workplaces = InstitutionsData.getInstitutionNumberOfWorkplaces(institutionName) --- * recipe = InstitutionsData.getInstitutionRecipe(institutionName, recipeIndex) --- * iconFilename = InstitutionsData.getInstitutionIcon(institutionName) --- --- And the following getter methods are all called with the institution's ID. --- You will have an ID instead of a display name when dealing with other data --- like recipes, species, etc. --- --- * name = InstitutionsData.getInstitutionNameByID(institutionID) --- * iconFilename = InstitutionsData.getInstitutionIconByID(institutionID) --- --- There are methods to retrieve the lists of required goods, workplaces, and --- recipes, but it is advised to instead use the getter methods --- getInstitutionRequiredGood, getInstitutionNumberOfWorkplaces, and --- getInstitutionRecipe with an index desired, which is good for loops. If --- you must get the tables, there are three "getAll" methods: --- --- * requiredGoodsTable = InstitutionsData.getAllInstitutionRequiredGoods(institutionName) --- * workplacesTable = InstitutionsData.getAllInstitutionWorkplaces(institutionName) --- * recipesTable = InstitutionsData.getAllInstitutionRecipes(institutionName) --- --- As a last resort, or if you need to transform the data structure, you can --- call the method getAllDataForInstitution(institutionName) or --- getAllDataForInstitutionByID(institutionID). These return a whole record --- from the data table corresponding to the required display name or ID. --- --- The data table for institutions has the following structure: --- --- institutionsTable = { --- ["institution1_ID"] = { --- ["id"] = "institution1_ID", --- ["displayName"] = "Plain Language Name", --- ["description"] = "A long string with some HTML entities too.", --- ["category"] = "Construction toolbar category", --- ["sizeX"] = 9, size in tiles --- ["sizeY"] = 9, size in tiles --- ["requiredGoods"] = { --- [1] = { ["stackSize"] = 99, ["goodID"] = "good1_ID" }, --- [2] = { ["stackSize"] = 99, ["goodID"] = "good2_ID" }, --- [3] = { ... } or missing if fewer --- }, --- ["constructionTime"] = 99, number of seconds --- ["cityScore"] = 99, points? --- ["movable"] = true or false, if it can be moved at any cost --- ["initiallyEssential"] = true or false, if a new-game-starting blueprint --- ["workplaces"] = { --- [1] = "Any", --- [2] = "Any", --- [3] = "Any", --- [4] = ... representing the number of workplaces, or missing if fewer --- }, --- ["recipes"] = { --- [1] = "recipe1_ID", --- [2] = "recipe2_ID", --- [3] = "recipe3_ID", --- [4] = ... or missing if fewer --- } --- }, --- ["institution2_ID"] = { --- ... --- }, --- ["institution3_ID"] = { --- ... --- }, --- ... --- } --- --- @module InstitutionsData local InstitutionsData = {} local CsvUtils = require("Module:CsvUtils") --region Private member variables --- Main data tables, like this: table[ID] = table containing data for that ID local institutionsTable --- Lookup map. Built once and reused on subsequent calls within this session, --- like this: table[display name] = institutionID local mapNamesToIDs --- Lookup map. Built once and reused on all subsequent calls within this --- session, like this: table[recipeID] = { institutionName1, --- institutionName2, ... } local mapRecipeIDsToInstitutionNames --endregion --region Private constants local DATA_TEMPLATE_NAME = "Template:Institutions_csv" local INDEX_ID = "id" local INDEX_NAME = "displayName" local INDEX_DESCRIPTION = "description" local INDEX_CATEGORY = "category" local INDEX_SIZE_X = "sizeX" local INDEX_SIZE_Y = "sizeY" local INDEX_CITY_SCORE = "cityScore" local INDEX_MOVABLE = "movable" local INDEX_INITIALLY_ESSENTIAL = "initiallyEssential" local INDEX_CONSTRUCTION_TIME = "constructionTime" local INDEX_REQUIRED_GOODS = "requiredGoods" -- table local INDEX_WORKPLACES = "workplaces" -- table local INDEX_RECIPES = "recipes" -- table local INDEX_CONSTRUCTION_GOODS_STACK_SIZE = "stackSize" local INDEX_CONSTRUCTION_GOODS_GOOD_ID = "goodID" local PATTERN_SPLIT_STACK_AND_ID = "(%d+)%s([%[%]%s%a]+)" --endregion --region Private methods --- --- Creates a new subtable containing the construction goods required for the --- specified institution. --- --- @param originalInstitution table institution data record from which to make subtable --- @param institutionsHeaderLookup table header lookup built from the CSV data --- @return table subtable with the required construction goods local function makeRequiredGoodsSubtable(originalInstitution, institutionsHeaderLookup) -- A constant we'll need only within this function. local REQ_GOOD_HEADER_BASE_STRING = "requiredGood" -- Copy the originals directly into a subtable. local requiredIndex1 = institutionsHeaderLookup[REQ_GOOD_HEADER_BASE_STRING .. "1"] local requiredIndex2 = institutionsHeaderLookup[REQ_GOOD_HEADER_BASE_STRING .. "2"] local requiredIndex3 = institutionsHeaderLookup[REQ_GOOD_HEADER_BASE_STRING .. "3"] local number1, id1 = originalInstitution[requiredIndex1]:match(PATTERN_SPLIT_STACK_AND_ID) local number2, id2 = originalInstitution[requiredIndex2]:match(PATTERN_SPLIT_STACK_AND_ID) local number3, id3 = originalInstitution[requiredIndex3]:match(PATTERN_SPLIT_STACK_AND_ID) -- don't add subtables that would just contain nils local requiredGoods = { number1 and id1 and { [INDEX_CONSTRUCTION_GOODS_STACK_SIZE] = number1, [INDEX_CONSTRUCTION_GOODS_GOOD_ID] = id1 } or nil, number2 and id2 and { [INDEX_CONSTRUCTION_GOODS_STACK_SIZE] = number2, [INDEX_CONSTRUCTION_GOODS_GOOD_ID] = id2 } or nil, number3 and id3 and { [INDEX_CONSTRUCTION_GOODS_STACK_SIZE] = number3, [INDEX_CONSTRUCTION_GOODS_GOOD_ID] = id3 } or nil } return requiredGoods end --- --- Creates a new subtable containing the workplaces available in the specified --- institution. --- --- @param originalInstitution table institution data record from which to make subtable --- @param institutionsHeaderLookup table header lookup built from the CSV data --- @return table subtable with the workplaces local function makeWorkplacesSubtable(originalInstitution, institutionsHeaderLookup) -- A constant we'll need only within this function. local WORKPLACE_HEADER_BASE_STRING = "workplace" -- Copy the originals directly into a subtable. local workplaceIndex1 = institutionsHeaderLookup[WORKPLACE_HEADER_BASE_STRING .. "1"] local workplaceIndex2 = institutionsHeaderLookup[WORKPLACE_HEADER_BASE_STRING .. "2"] local workplaceIndex3 = institutionsHeaderLookup[WORKPLACE_HEADER_BASE_STRING .. "3"] local workplaceIndex4 = institutionsHeaderLookup[WORKPLACE_HEADER_BASE_STRING .. "4"] local workplace1 = originalInstitution[workplaceIndex1] local workplace2 = originalInstitution[workplaceIndex2] local workplace3 = originalInstitution[workplaceIndex3] local workplace4 = originalInstitution[workplaceIndex4] -- if it's not an empty string, then save that to the table, otherwise nil local workplaces = { (workplace1 ~= "" and workplace1) or nil, (workplace2 ~= "" and workplace2) or nil, (workplace3 ~= "" and workplace3) or nil, (workplace4 ~= "" and workplace4) or nil } return workplaces end --- --- Creates a new subtable containing the recipes available in the specified --- institution. --- --- @param institutionName string the name of the institution --- @param originalInstitution table institution data record from which to make subtable --- @param institutionsHeaderLookup table header lookup built from the CSV data --- @return table subtable with the recipe IDs local function makeRecipesSubtable(institutionName, originalInstitution, institutionsHeaderLookup) -- A constant we'll need only within this function. local LOOKUP_RECIPE_BASE_STRING = "recipe" -- Copy the originals directly into a subtable. local recipeIndex1 = institutionsHeaderLookup[LOOKUP_RECIPE_BASE_STRING .. "1"] local recipeIndex2 = institutionsHeaderLookup[LOOKUP_RECIPE_BASE_STRING .. "2"] local recipeIndex3 = institutionsHeaderLookup[LOOKUP_RECIPE_BASE_STRING .. "3"] local recipeIndex4 = institutionsHeaderLookup[LOOKUP_RECIPE_BASE_STRING .. "4"] local recipe1 = originalInstitution[recipeIndex1] local recipe2 = originalInstitution[recipeIndex2] local recipe3 = originalInstitution[recipeIndex3] local recipe4 = originalInstitution[recipeIndex4] local recipes = { (recipe1 ~= "" and recipe1) or nil, (recipe2 ~= "" and recipe2) or nil, (recipe3 ~= "" and recipe3) or nil, (recipe4 ~= "" and recipe4) or nil } -- Make reverse-lookup map. if recipe1 and recipe1 ~= "" then if not mapRecipeIDsToInstitutionNames[recipe1] then mapRecipeIDsToInstitutionNames[recipe1] = {} end table.insert( mapRecipeIDsToInstitutionNames[recipe1], institutionName) end if recipe2 and recipe2 ~= "" then if not mapRecipeIDsToInstitutionNames[recipe2] then mapRecipeIDsToInstitutionNames[recipe2] = {} end table.insert( mapRecipeIDsToInstitutionNames[recipe2], institutionName) end if recipe3 and recipe3 ~= "" then if not mapRecipeIDsToInstitutionNames[recipe3] then mapRecipeIDsToInstitutionNames[recipe3] = {} end table.insert( mapRecipeIDsToInstitutionNames[recipe3], institutionName) end if recipe4 and recipe4 ~= "" then if not mapRecipeIDsToInstitutionNames[recipe4] then mapRecipeIDsToInstitutionNames[recipe4] = {} end table.insert( mapRecipeIDsToInstitutionNames[recipe4], institutionName) end return recipes end --- --- Transforms the originalInstitutionsTable returned from CSV processing to be --- more conducive to member functions looking up data. Converts text strings --- into subtables. Converts header row into field keys on every record and --- stores records by id rather than arbitrary integer. --- --- @param originalInstitutionsTable table of CSV-based data, with header row, data rows --- @param institutionsHeaderLookup table lookup table of headers to get indexes --- @return table better structured with IDs as keys local function restructureInstitutionsTable(originalInstitutionsTable, institutionsHeaderLookup) -- A few constants we need only in this function. local DATA_ROWS = 2 local INDEX_ORIGINAL_ID = 1 local INDEX_ORIGINAL_NAME = 2 local INDEX_ORIGINAL_DESCRIPTION = 3 local INDEX_ORIGINAL_CATEGORY = 4 local INDEX_ORIGINAL_SIZE_X = 5 local INDEX_ORIGINAL_SIZE_Y = 6 -- Required goods are indexes 7, 8, 9 local INDEX_ORIGINAL_CONSTRUCTION_TIME = 10 local INDEX_ORIGINAL_CITY_SCORE = 11 local INDEX_ORIGINAL_MOVABLE = 12 local INDEX_ORIGINAL_ESSENTIAL = 13 mapNamesToIDs = {} mapRecipeIDsToInstitutionNames = {} local newInstitutionsTable = {} for _, originalInstitution in ipairs(originalInstitutionsTable[DATA_ROWS]) do -- Copy over the content, mapping unhelpful indexes into headers keys. local newInstitution = {} newInstitution[INDEX_ID] = originalInstitution[INDEX_ORIGINAL_ID] newInstitution[INDEX_NAME] = originalInstitution[INDEX_ORIGINAL_NAME] newInstitution[INDEX_DESCRIPTION] = originalInstitution[INDEX_ORIGINAL_DESCRIPTION] newInstitution[INDEX_CATEGORY] = originalInstitution[INDEX_ORIGINAL_CATEGORY] newInstitution[INDEX_SIZE_X] = originalInstitution[INDEX_ORIGINAL_SIZE_X] newInstitution[INDEX_SIZE_Y] = originalInstitution[INDEX_ORIGINAL_SIZE_Y] newInstitution[INDEX_CITY_SCORE] = originalInstitution[INDEX_ORIGINAL_CITY_SCORE] newInstitution[INDEX_MOVABLE] = "TRUE" == originalInstitution[INDEX_ORIGINAL_MOVABLE] newInstitution[INDEX_INITIALLY_ESSENTIAL] = "TRUE" == originalInstitution[INDEX_ORIGINAL_ESSENTIAL] newInstitution[INDEX_CONSTRUCTION_TIME] = originalInstitution[INDEX_ORIGINAL_CONSTRUCTION_TIME] newInstitution[INDEX_REQUIRED_GOODS] = makeRequiredGoodsSubtable(originalInstitution, institutionsHeaderLookup) newInstitution[INDEX_WORKPLACES] = makeWorkplacesSubtable(originalInstitution, institutionsHeaderLookup) newInstitution[INDEX_RECIPES] = makeRecipesSubtable(newInstitution[INDEX_NAME], originalInstitution, institutionsHeaderLookup) newInstitutionsTable[ newInstitution[INDEX_ID] ] = newInstitution -- Also populate the map for looking up IDs with display names mapNamesToIDs[ newInstitution[INDEX_NAME] ] = newInstitution[INDEX_ID] end return newInstitutionsTable end --- --- Data loader function that uses the utility module and restructures the data --- to be easier to access for invoking methods and later method calls. This --- method is automatically called by all public member functions if the main --- data table has not yet been populated in the current session. local function loadData() -- Utility module retrieves the data as basic, flat lua tables. local originalInstitutionsTable, institutionsHeaderLookup = CsvUtils.extractTables(DATA_TEMPLATE_NAME) -- Now restructure to be more conducive. institutionsTable = restructureInstitutionsTable(originalInstitutionsTable, institutionsHeaderLookup) end --- --- Uses the display name, which people are more familiar with, to find the --- encoded ID of the institution. Useful for retrieving the data that is --- indexed by ID. --- --- Returns nil if the institution with the specified name is not found. --- --- @param displayName string plain-language name of the institution to find --- @return string ID of the institution found, or nil if not found local function findInstitutionIDByName(displayName) -- At runtime, this should never be nil or empty, so throw an error. if not displayName or displayName == "" then error("Parameter is nil or empty for the institution's name: " .. displayName .. ".") end if not institutionsTable then loadData() end return mapNamesToIDs[displayName] end --endregion --region Public methods --- Retrieve the whole table of data for the specified institution. Instead of --- this, you should probably be calling the individual getter methods. --- --- Throws an error if called with nil or empty string. Returns nil if the --- specified institution cannot be found. --- --- @param institutionID string ID of the institution --- @return table containing the data with key-value pairs, or nil if not found function InstitutionsData.getAllDataForInstitutionByID(institutionID) -- At runtime, this should never be nil or empty. if not institutionID or institutionID == "" then error("Parameter is nil or empty for the institution's ID.") end if not institutionsTable then loadData() end return institutionsTable[institutionID] end --- Retrieve the whole table of data for the specified institution. Instead of --- this, you should probably be calling the individual getter methods. --- --- Throws an error if called with nil or empty string. Returns nil if the --- specified institution cannot be found. --- --- @param displayName string plain language name of the institution --- @return table containing the data with key-value pairs, or nil if not found function InstitutionsData.getAllDataForInstitution(displayName) -- At runtime, this should never be nil or empty. if not displayName or displayName == "" then error("Parameter is nil or empty for the institution's name.") end if not institutionsTable then loadData() end local institutionID = findInstitutionIDByName(displayName) if not institutionID then return nil end return institutionsTable[institutionID] end --- --- Retrieves the ID for the institution specified by its plain language --- display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return string the ID of the specified institution function InstitutionsData.getInstitutionID(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_ID] end --- --- Retrieves the description for the institution specified by its plain --- language display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return string the in-game description of the specified institution function InstitutionsData.getInstitutionDescription(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_DESCRIPTION] end --- --- Retrieves the construction toolbar category for the institution specified --- by its plain language display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return string the category of the specified institution function InstitutionsData.getInstitutionCategory(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_CATEGORY] end --- --- Retrieves the 2x2 size for the institution specified by its plain language --- display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return number the X-size of the institution ---@return number the Y-size of the institution function InstitutionsData.getInstitutionSize(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_SIZE_X], institution[INDEX_SIZE_Y] end --- --- Retrieves the goods required for construction for the institution specified --- by its plain language display name, in a table that looks like this: --- --- ["requiredGoods"] = { --- [1] = { ["stackSize"] = 99, ["goodID"] = "good1_ID" }, --- [2] = { ["stackSize"] = 99, ["goodID"] = "good2_ID" }, --- [3] = { ... } or missing if fewer --- } --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return table of required goods function InstitutionsData.getAllInstitutionRequiredGoods(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_REQUIRED_GOODS] end --- --- Retrieves the specified required construction good for the institution --- specified by its plain language display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@param requirementIndex number which construction good to retrieve ---@return string the ID of the good that is required, or nil if none ---@return number the stack size of that good, or nil if none function InstitutionsData.getInstitutionRequiredGood(displayName, requirementIndex) local requiredGoods = InstitutionsData.getAllInstitutionRequiredGoods(displayName) if not requiredGoods then return nil end local requirement = requiredGoods[requirementIndex] if not requirement then return nil end return requirement[INDEX_CONSTRUCTION_GOODS_GOOD_ID], requirement[INDEX_CONSTRUCTION_GOODS_STACK_SIZE] end --- --- Retrieves the construction time for the institution specified by its plain --- language display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return number of seconds it takes to construct the institution function InstitutionsData.getInstitutionConstructionTime(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_CONSTRUCTION_TIME] end --- --- Retrieves the city score awarded for the institution specified by its plain --- language display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return number of points for city score from having the institution function InstitutionsData.getInstitutionCityScore(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_CITY_SCORE] end --- --- Retrieves whether the institution specified by its plain language display --- name can be moved, at any cost. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return boolean of whether the institution can be moved function InstitutionsData.isInstitutionMovable(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_MOVABLE] end --- --- Retrieves whether the institution specified by its plain language display --- name has an essential starting blueprint for a new game profile. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return boolean of whether the institution's blueprint is essential function InstitutionsData.isInstitutionInitiallyEssential(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_INITIALLY_ESSENTIAL] end --- --- Retrieves the table of workplaces for the institution specified by its --- plain language display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return table of workplaces function InstitutionsData.getAllInstitutionWorkplaces(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_WORKPLACES] end --- --- Retrieves the number of workplaces for the institution specified by its --- plain language display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return number of workplaces function InstitutionsData.getInstitutionNumberOfWorkplaces(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return #institution[INDEX_WORKPLACES] end --- --- Retrieves the table of recipes for the institution specified by its --- plain language display name, in a table that looks like this: --- --- ["recipes"] = { --- [1] = "recipe1_ID", --- [2] = "recipe2_ID", --- [3] = "recipe3_ID", --- [4] = ... or missing if fewer --- } --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return table of recipe IDs function InstitutionsData.getAllInstitutionRecipes(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end return institution[INDEX_RECIPES] end --- --- Retrieves the specified recipe at the institution specified by its plain --- language display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@param recipeIndex number the index of the recipe ID ---@return string the ID of the specified recipe function InstitutionsData.getInstitutionRecipe(displayName, recipeIndex) local recipes = InstitutionsData.getAllInstitutionRecipes(displayName) if not recipes then return nil end return recipes[recipeIndex] end --- --- Retrieves the icon filename for the institution specified by its plain --- language display name. --- --- Returns nil if the institution named was not found. --- ---@param displayName string the plain language name of the institution ---@return string the institution's icon filename, including the extension function InstitutionsData.getInstitutionIcon(displayName) local institution = InstitutionsData.getAllDataForInstitution(displayName) if not institution then return nil end -- the base string of the icon is the ID. It has to be not nil to -- concatenate if institution[INDEX_ID] then return institution[INDEX_ID] .. "_icon.png" else return nil end end --- --- Retrieves the plain language display name for the institution specified by --- its ID. --- --- Returns nil if the institution named was not found. --- ---@param institutionID string the ID of the institution ---@return string the institution's name as seen in-game function InstitutionsData.getInstitutionNameByID(institutionID) local institution = InstitutionsData.getAllDataForInstitutionByID(institutionID) if not institution then return nil end return #institution[INDEX_NAME] end --- --- Retrieves theicon filename for the the institution specified by its ID. --- --- Returns nil if the institution named was not found. --- ---@param institutionID string the ID of the institution ---@return string the institution's icon filename, including the extension function InstitutionsData.getInstitutionIconByID(institutionID) local institution = InstitutionsData.getAllDataForInstitutionByID(institutionID) if not institution then return nil end -- the base string of the icon is the ID. It has to be not nil to -- concatenate if institution[INDEX_ID] then return institution[INDEX_ID] .. "_icon.png" else return nil end end --- --- Retrieve all display names of institutions that have the specified recipe --- ID. --- ---@param recipeID string the ID of the recipe ---@return table of institution names that produce the specified recipe function InstitutionsData.getInstitutionNamesWithRecipeID(recipeID) -- At runtime, this should never be nil or empty. if not recipeID or recipeID == "" then error("Parameter is nil or empty for product ID.") end if not institutionsTable then loadData() end return mapRecipeIDsToInstitutionNames[recipeID] end --endregion return InstitutionsData