Module:Item recipe: Difference between revisions

From Space Station 14 Wiki
(wip)
(wip)
Line 5: Line 5:
local p = {} --p stands for package
local p = {} --p stands for package
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs
local item = require('Module:Item')


local recipes_by_recipe_method = {
local recipes_by_recipe_method = {
Line 54: Line 55:


-- Searches for recipes using production method and a product.
-- Searches for recipes using production method and a product.
-- Product is the item ID that results from a recipe.
-- Product is the item that results from a recipe. It can be a name, alias or an ID.
-- Name and alias can both be written in any case.
-- Returns an array of recipes found.
-- Returns an array of recipes found.
function lookup_recipes_by_method_and_product(method, product)
function lookup_recipes_by_method_and_product(method, product)
assert_value_not_nil(method, "method was not provided")
assert_value_not_nil(method, "method was not provided")
assert_value_not_nil(product, "product was not provided")
assert_value_not_nil(product, "product was not provided")
-- lookup the actual item ID
product = item.lookup_item_id_by_name_and_amount({ [1] = product, [2] = "1" })


if method == "lathe" then
if method == "lathe" then
Line 86: Line 91:


local method = args[1]
local method = args[1]
assert_value_not_nil(method, "method was not provided")
assert_value_not_nil(method, "failed to generate a recipe skeleton: method was not provided")
local product = args[2]
local product = args[2]
assert_value_not_nil(product, "product was not provided")
assert_value_not_nil(product, "failed to generate a recipe skeleton: product was not provided")


local matching_recipes = lookup_recipes_by_method_and_product(method, product)
local matching_recipes = lookup_recipes_by_method_and_product(method, product)
local matching_recipes_len = numeric_table_length(matching_recipes)
local matching_recipes_len = numeric_table_length(matching_recipes)
mw.logObject({ method = method, product = product })


local container_el = mw.html.create("div")
local container_el = mw.html.create("div")
Line 99: Line 102:


if matching_recipes_len == 0 then
if matching_recipes_len == 0 then
return container_el
error("failed to generate a recipe skeleton: no recipe found for product '" .. product .. "' that's made using '" .. method .. "'")
elseif matching_recipes_len == 1 then
elseif matching_recipes_len == 1 then
local matching_recipe = matching_recipes[1]
local matching_recipe = matching_recipes[1]
Line 106: Line 109:


for material, cost in pairs(matching_recipe.materials) do
for material, cost in pairs(matching_recipe.materials) do
container_el:node(frame:preprocess("{{item|" .. material .. "|" .. cost .. "}}"))
container_el:node(mw:getCurrentFrame():preprocess("{{item|" .. material .. "|" .. cost .. "}}"))
end
end



Revision as of 11:10, 24 August 2024

Module documentation
View or edit this documentation (about module documentation)

Implements {{item recipe}}.

JSON files

JSON files that are updated automatically, syncing with the upstream:

Warning
Do not make changes to the above JSON files - any changes made will be erased on next update.

JSON files that are filled manually:

  • Module:Item recipe/order of materials.json - a 1 to 1 mapping of recipe materials to order at which they appear in recipes. Less number = higher order. Materials that do not have an order defined here, will appear after those that do.
  • Module:Item recipe/product overrides.json - a 1 to 1 mapping of recipe products to item IDs. Not all products are the same as item IDs they "represent", so sometimes a connection needs to be established explicitly.

-- Contains utilities for working with in-game items.

-- todo: material sorting. based on alphabetical sorting? maybe at .json generation step, convert materials to an array?

local p = {} --p stands for package
local getArgs = require('Module:Arguments').getArgs
local item = require('Module:Item')

local recipes_by_recipe_method = {
	lathe = mw.loadJsonData("Module:Item recipe/recipes by method/lathe.json")
}

-- A table containing item recipes, identified by recipe IDs.
-- local recipes_by_recipe_id =

-- A table containing item recipe categories, identified by recipe category IDs.
-- local recipy_categories_by_recipe_category_id = mw.loadJsonData("Module:Item recipe/recipy categories by recipe category id.json")

-- ====================


function numeric_table_length(t)
	local count = 0
	for _ in ipairs(t) do count = count + 1 end
	return count
end

function table_length(t)
	local count = 0
	for _ in pairs(t) do count = count + 1 end
	return count
end

function table_has_value(tab, val)
	for _, value in ipairs(tab) do
		if value == val then
			return true
		end
	end

	return false
end

function assert_value_not_nil(value, error_message)
	if value == nil then
		if error_message == nil then
			error("value is nil")
		else
			error(error_message)
		end
	end
end

-- ====================

-- Searches for recipes using production method and a product.
-- Product is the item that results from a recipe. It can be a name, alias or an ID.
-- Name and alias can both be written in any case.
-- Returns an array of recipes found.
function lookup_recipes_by_method_and_product(method, product)
	assert_value_not_nil(method, "method was not provided")
	assert_value_not_nil(product, "product was not provided")
	
	-- lookup the actual item ID
	product = item.lookup_item_id_by_name_and_amount({ [1] = product, [2] = "1" })

	if method == "lathe" then
		local matching_recipes = {}
		for _, recipe in ipairs(recipes_by_recipe_method.lathe) do
			local recipe_result = recipe.result
			-- todo err message
			assert_value_not_nil(recipe_result)

			if recipe_result == product then
				table.insert(matching_recipes, recipe)
			end
		end

		return matching_recipes
	else
		error("unknown recipe method: " .. method)
	end
end

-- ====================

-- Generates an HTML element, containing recipe components used to produce given item with a given method.
-- Returns a DIV containg {{item}}s.
function p.generate_recipe_skeleton(frame)
	local args = getArgs(frame)

	local method = args[1]
	assert_value_not_nil(method, "failed to generate a recipe skeleton: method was not provided")
	local product = args[2]
	assert_value_not_nil(product, "failed to generate a recipe skeleton: product was not provided")

	local matching_recipes = lookup_recipes_by_method_and_product(method, product)
	local matching_recipes_len = numeric_table_length(matching_recipes)

	local container_el = mw.html.create("div")
		:addClass("item-recipe")

	if matching_recipes_len == 0 then
		error("failed to generate a recipe skeleton: no recipe found for product '" .. product .. "' that's made using '" .. method .. "'")
	elseif matching_recipes_len == 1 then
		local matching_recipe = matching_recipes[1]

		assert_value_not_nil(matching_recipe.materials, "'materials' field is nil for recipe " .. matching_recipe.id)

		for material, cost in pairs(matching_recipe.materials) do
			container_el:node(mw:getCurrentFrame():preprocess("{{item|" .. material .. "|" .. cost .. "}}"))
		end

		return container_el
			:allDone()
	else
		error("failed to generate a recipe skeleton: found multiple matching recipes for given method " .. method .. " and product " .. product)
	end
end


-- -- Generates a list of items needed for a recipe, along with exact amounts.
-- -- Needs a recipe ID passed as a single frame argument.
-- -- Uses {{Item}} to produce the items. Returns a div containing them.
-- function p.generate_recipe_items(frame)
-- 	local recipe_id = args[1]
-- 	assert_value_not_nil(recipe_id, "recipe ID was not provided")
-- end

return p