Module:RecipeData: Difference between revisions

From Against the Storm Official Wiki
(fixed the processing in getter for ingredients and quantities)
(more dumb typos, this time in a for loop for same getter)
Line 250: Line 250:
local returnQuantities = {}
local returnQuantities = {}
for i, place in tRecipe.places do
for i, place in ipairs(tRecipe.places) do
returnQuantities[i] = place.quantities
returnQuantities[i] = place.quantities
end
end

Revision as of 04:48, 8 February 2023

Documentation for this module may be created at Module:RecipeData/doc

-------------------------------------------------------------------------------
-- 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
	-- 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={{3,2,2,2}}, out=10} } },
	["meat"] = { product="Meat", pattern={ {"Plant Fiber","Reeds","Grain","Vegetables"} },
		places={ {building="Ranch", stars=1, speed="01:24", quantities={{8,8,8,5}}, out=10} } },
	["mushrooms"] = { product="Mushrooms", pattern={ {"Drizzle Water"} },
		places={ {building="Greenhouse", stars=2, speed="01:24", quantities={{4}}, 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(strArg)
	
	if not strArg then
		return "Recipe_Data Error: product not given."
	end

	-- normalize input using resource normalizer method
    local strProductName = RecipeData.normalizeProductName(strArg)
	
	-- 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(strArg1, strArg2)
	
	if not strArg1 then
		 return "Recipe_Data Error: product not given."
	end
	if not strArg2 then
		return "Recipe_Data Error: building not given."
	end
	
	-- normalize inputs using resource and building normalizer methods
    local strProductName = RecipeData.normalizeProductName(strArg1)
	local strBuildingName = RecipeData.normalizeBuildingName(strArg2)
	
	-- 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 table to return
	local 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 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
	
	local returnQuantities = {}
	for i, place in ipairs(tRecipe.places) do
		returnQuantities[i] = place.quantities
	end
	
	-- the pattern has the same structure as _EACH_ item in the returnQuantities list
	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(strArg2)
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