Module:RecipeData

--- -- Lua storage table for looking up wiki pages, names, and recipes -- based on in-game names. All data is in English. -- -- The table contains some deconfliction, but only for spaces, apostrophes, and -- some singular/plural. -- Use in-game names for things, and help keep this table updated as the game -- is updated. -- -- Using the table requires a locally defined lookup function that performs -- a string.lower on the argument so that the lookup table can accept any case -- and still function properly. Otherwise, we would need the table to define -- both Berries = "Berries" and berries = "Berries" which would multiply our -- work. ---

-- for returning when REQUIRE'd by other Lua modules. local RecipeData = {}

local ResourceData = require("Module:ResourceData") -- need to reuse the normalize method local BuildingData = require("Module:BuildingData") -- need to reuse the normalize method

--- -- Constants --- -- if needed

--- -- Main data table, with string keys and string values. -- Some of these are defined inline with string.lower to make the key easier -- to spell and read correctly. ---

-- a design decision of this table is to make the key the same as the product name. -- (the lookup methods will automatically make it lowercase.) -- that way, whenever .product is referenced, it can be used again to retrieve -- the rest of the data. local tableData = { ---	-- Recipes -- product: string: name of the product, as it appears in the game -- pattern: table of tables: the basic components of the recipe that don't depend on buildings, stars, or numbers of things. -- pattern/1..n: table of strings: use as many inner tables as necessary to represent each the ingredients of the recipe (no numbers here; they go with the stars). if an ingredient is required, then use a table with only one string in it, like this: {"Flour"}. please use the same order as in the in-game recipe book, left-to-right, for consistency -- places: table: 1..n: the info that depends on the buildings and stars -- places/1..n: table of tables: the building, stars, the speed (production time), the number of input resources (including all options) required, and the number of output yield (usually 10). please use the same order as the in-game recipe book, top-to-bottom, for consistency. -- building: string: building name, as written in-game (spelling and punctuation count) -- stars: integer: stars number, 0 (red) to 3 -- speed: string: production time, in the format 00:00 for minutes and seconds -- places/quantities: array of arrays: corresponding to the order of ingredients in the pattern table. -- places/quantities/1..n: array of integers: number of required ingredients for each alternative -- out: integer: count of product (usually 10) ---	-- Raw Food ["eggs"] = { product="Eggs", pattern={ {"Grain","Insects","Reeds","Berries"} }, places={ {building="Ranch", stars=1, speed="01:24", quantities=, out=10} } }, ["meat"] = { product="Meat", pattern={ {"Plant Fiber","Reeds","Grain","Vegetables"} }, places={ {building="Ranch", stars=1, speed="01:24", quantities=, out=10} } }, ["mushrooms"] = { product="Mushrooms", pattern={ {"Drizzle Water"} }, places={ {building="Greenhouse", stars=2, speed="01:24", quantities=, out=4} } }, -- Complex Food ["biscuits"] = { product="Biscuits", pattern={ {"Flour"}, {"Vegetables","Berries","Roots"} }, places={ {building="Field Kitchen", stars=0, speed="02:06", quantities={{10},{4,4,4}}, out=10}, {building="Bakery", stars=2, speed="02:06", quantities={{8},{3,3,3}}, out=10}, {building="Cookhouse", stars=2, speed="02:06", quantities={{8},{3,3,3}}, out=10}, {building="Smelter", stars=1, speed="02:06", quantities={{8},{4,4,4}}, out=10}, {building="Apothecary", stars=2, speed="02:06", quantities={{8},{3,3,3}}, out=10} } },	["jerky"] = { product="Jerky" }, ["pickled goods"] = { product="Pickled Goods" }, ["pie"] = { product="Pie" }, ["skewers"] = { product="Skewers" }, -- Building Materials ["bricks"] = { product="Bricks" }, ["fabric"] = { product="Fabric" }, ["planks"] = { product="Planks" }, ["parts"] = { product="Parts" }, ["wildfire essence"] = { product="Wildfire Essence" }, -- Consumable Items ["coats"] = { product="Coats" }, ["ale"] = { product="Ale" }, ["cosmetics"] = { product="Cosmetics" }, ["incense"] = { product="Incense" }, ["scrolls"] = { product="Scrolls" }, ["training gear"] = { product="Training Gear" }, ["wine"] = { product="Wine" }, -- Crafting Materials ["clay"] = { product="Clay" }, ["copper ore"] = { product="Copper Ore" }, ["crystalized dew"] = { product="Crystalized Dew" }, ["grain"] = { product="Grain" }, ["herbs"] = { product="Herbs" }, ["leather"] = { product="Leather" }, ["plant fiber"] = { product="Plant Fiber" }, ["reeds"] = { product="Reeds" }, ["resin"] = { product="Resin" }, ["sparkdew"] = { product="Sparkdew" }, ["stone"] = { product="Stone" }, -- Refined Crafting Materials ["barrels"] = { product="Barrels" }, ["copper bars"] = { product="Copper Bars" }, ["flour"] = { product="Flour" }, ["pigment"] = { product="Pigment" }, ["pottery"] = { product="Pottery" }, ["waterskins"] = { product="Waterskins" }, -- Trade Goods ["amber"] = { product="Amber" }, ["ancient tablet"] = { product="Ancient Tablet" }, ["pack of building materials"] = { product="Pack of Building Materials" }, ["pack of crops"] = { product="Pack of Crops"}, ["pack of luxury goods"] = { product="Pack of Luxury Goods" }, ["pack of provisions"] = { product="Pack of Provisions" }, ["pack of trade goods"] = { product="Pack of Trade Goods" }, -- Meta resources ["artifacts"] = { product="Artifacts" }, ["food stockpiles"] = { product="Food Stockpiles" }, ["machinery"] = { product="Machinery" }, -- Fuel & Exploration ["coal"] = { product="Coal" }, ["oil"] = { product="Oil" }, ["sea marrow"] = { product="Sea Marrow" }, ["wood"] = { product="Wood" }, ["simple tools"] = { product="Simple Tools" }, ["infused tools"] = { product="Infused Tools" }, ["purging fire"] = { product="Purging Fire" }, -- Rain ["clearance water"] = { product="Clearance Water" }, ["drizzle water"] = { product="Drizzle Water" }, ["storm water"] = { product="Storm Water" } }

--- -- Main lookup functions -- Accepts the in-game name and returns the recipe associated with the -- specified product. ---

-- returns the whole recipe table for a given product -- need to run normalize function first -- this (currently) returns a reference, not a copy, so be careful not to change the data function RecipeData.getAllRecipes(argProductName) if not argProductName then return "Recipe_Data Error: product not given." end

-- normalize input using resource normalizer method local strProductName = RecipeData.normalizeProductName(argProductName) -- Get it from the big table above and return the whole pattern and places contents return tableData[strProductName] end

-- extract the pattern from the recipe table -- hide the internals from calling modules function RecipeData.getPatternFromRecipe(tRecipe)

return tRecipe.pattern end

-- extract the recipe specifics for a given building. -- this will return a reduced recipe table (following the specification above), -- with only one place, corresponding to the provided building. -- this function returns raw data, so other helper functions are necessary to -- hide internals from calling methods. -- error handling will be necessary by calling function. function RecipeData.getRecipeAtBuilding(argProductName, argBuildingName) if not argProductName then return "Recipe_Data Error: product not given." end if not argBuildingName then return "Recipe_Data Error: building not given." end -- normalize inputs using resource and building normalizer methods local strProductName = RecipeData.normalizeProductName(argProductName) local strBuildingName = RecipeData.normalizeBuildingName(argBuildingName) -- start with the table for the product, then find the building within its places local tRecipe = tableData[strProductName] -- and make sure there's something to do	if not tRecipe then return nil end -- build a separate, simplified table to return local tableToReturn = {} tableToReturn.product = tRecipe.product tableToReturn.pattern = tRecipe.pattern -- loop over the places. once the building matches, copy just that place (reference) into the table to return for _, place in pairs(tRecipe.places) do		if string.lower(place.building) == strBuildingName then tableToReturn.places = {place} return tableToReturn end end -- the building was not found, so return nothing return nil end

-- hide the internals of the previous methods. -- extract a list of buildings and stars, then the caller can decide how to output the list function RecipeData.getBuildingsAndStarsLists(tRecipe) -- make sure we have something to work with if not tRecipe or not tRecipe.places or #tRecipe.places < 1 then return nil, nil end local strBuildings = {} local intStars = {} -- loop through the places, extracting the strings and integers for the buildings and stars -- and storing them in the tables that will be returned for i, place in pairs(tRecipe.places) do		-- make sure no nil values or we don't need to continue if not place.building or not place.stars then return nil, nil end strBuildings[i] = place.building intStars[i] = place.stars end return strBuildings, intStars end

-- hide the internals of the above methods. -- extract lists of ingredients and quantity for a specific recipe at a specific building function RecipeData.getIngredientsAndQuantities(tRecipe) -- make sure we have something to work with if not tRecipe or not tRecipe.places or 0 == #tRecipe.places then return nil, nil end

-- the pattern has the same structure as _EACH_ item in the returnQuantities list local returnQuantities = {} for i, place in ipairs(tRecipe.places) do		returnQuantities[i] = place.quantities end return tRecipe.pattern, returnQuantities end

-- loop over the places and make a new list of extracting all the production times function RecipeData.getProductionSpeed(tRecipe) -- make sure we have something to work with if not tRecipe or not tRecipe.places or 0 == #tRecipe.places then return nil end local speeds = {} for i, place in ipairs(tRecipe.places) do		speeds[i] = place.speed end return speeds end

-- loop over the places and make a new list of extracting all the products and number output -- at this point, the key has been lost, so we use the product field of the recipe table function RecipeData.getProductAndNumbers(tRecipe)

-- make sure we have something to work with if not tRecipe or not tRecipe.places or 0 == #tRecipe.places then return nil, nil end local numbers = {} for i, place in ipairs(tRecipe.places) do		numbers[i] = place.out end return tRecipe.product, numbers end

--- -- Helper functions ---

-- Normalize the argument to the standard in-game name, and the one that -- is used as the key in the big lookup table. -- -- These functions call external normalize methods. function RecipeData.normalizeProductName(strArg) -- invoke the ResourceData.normalize method, since we're dealing in resource names return ResourceData.normalizeName(strArg) end

function RecipeData.normalizeBuildingName(strArg) -- invoke the BuildingData.normalize method, since we're dealing in building names return BuildingData.normalizeName(strArg) end

-- accepts a 2x2 table in the format of pattern and quantities in tableData above function RecipeData.copyPatternTypeTable(tArg)

local tReturn = {} for k, v in ipairs(tArg) do		for ik, iv in ipairs(tArg[k]) do			tReturn[k][ik] = iv		end end return tReturn end

-- accepts a complex table in the format of places in tableData above function RecipeData.copyPlaceTypeTable(tArg)

local tReturn = {} tReturn["building"] = tArg["building"] tReturn["stars"] = tArg["stars"] tReturn["speed"] = tArg["speed"] tReturn["out"] = tArg["out"] tReturn["places"] = copyPatternTypeTable(tArg["places"])

return tReturn end

--- -- Return when required into another Module. --- return RecipeData