mirror of
https://github.com/mt-mods/pipeworks.git
synced 2024-09-07 22:06:48 +02:00
Autocrafter multi group ingredient (#115)
* check for non-zero group value in theory groups can have negative values too. * fix #114 multi group recipe items Fix the bug that prevented crafting with recipes that had ingredients that need to match multiple groups. * comments and whitespace changes * fix faulty empty table check
This commit is contained in:
parent
8828183bef
commit
1577af738f
@ -4,6 +4,7 @@ local S = minetest.get_translator("pipeworks")
|
||||
local autocrafterCache = {}
|
||||
|
||||
local craft_time = 1
|
||||
local next = next
|
||||
|
||||
local function count_index(invlist)
|
||||
local index = {}
|
||||
@ -48,7 +49,9 @@ local function get_matching_craft(output_name, example_recipe)
|
||||
elseif recipe_item_name:sub(1, 6) == "group:" then
|
||||
group = recipe_item_name:sub(7)
|
||||
for example_item_name, _ in pairs(index_example) do
|
||||
if minetest.get_item_group(example_item_name, group) > 0 then
|
||||
if minetest.get_item_group(
|
||||
example_item_name, group) ~= 0
|
||||
then
|
||||
score = score + 1
|
||||
break
|
||||
end
|
||||
@ -89,22 +92,27 @@ local function get_craft(pos, inventory, hash)
|
||||
return craft
|
||||
end
|
||||
|
||||
-- From a consumption table with groups and an inventory index, build
|
||||
-- a consumption table without groups
|
||||
-- From a consumption table with groups and an inventory index,
|
||||
-- build a consumption table without groups
|
||||
local function calculate_consumption(inv_index, consumption_with_groups)
|
||||
inv_index = table.copy(inv_index)
|
||||
consumption_with_groups = table.copy(consumption_with_groups)
|
||||
|
||||
-- table of items to actually consume
|
||||
local consumption = {}
|
||||
local groups = {}
|
||||
-- table of ingredients defined as one or more groups each
|
||||
local grouped_ingredients = {}
|
||||
|
||||
-- First consume all non-group requirements
|
||||
-- This is done to avoid consuming a non-group item which is also
|
||||
-- in a group
|
||||
-- This is done to avoid consuming a non-group item which
|
||||
-- is also in a group
|
||||
for key, count in pairs(consumption_with_groups) do
|
||||
if key:sub(1, 6) == "group:" then
|
||||
groups[#groups + 1] = key:sub(7, #key)
|
||||
-- build table with group recipe items while looping
|
||||
grouped_ingredients[key] = key:sub(7):split(',')
|
||||
else
|
||||
-- if the item to consume doesn't exist in inventory
|
||||
-- or not enough of them, abort crafting
|
||||
if not inv_index[key] or inv_index[key] < count then
|
||||
return nil
|
||||
end
|
||||
@ -118,28 +126,45 @@ local function calculate_consumption(inv_index, consumption_with_groups)
|
||||
end
|
||||
end
|
||||
|
||||
-- helper function to resolve matching ingredients with multiple group
|
||||
-- requirements
|
||||
local function ingredient_groups_match_item(ingredient_groups, name)
|
||||
local found = 0
|
||||
local count_ingredient_groups = #ingredient_groups
|
||||
for i = 1, count_ingredient_groups do
|
||||
if minetest.get_item_group(name,
|
||||
ingredient_groups[i]) ~= 0
|
||||
then
|
||||
found = found + 1
|
||||
end
|
||||
end
|
||||
return found == count_ingredient_groups
|
||||
end
|
||||
|
||||
-- Next, resolve groups using the remaining items in the inventory
|
||||
local take
|
||||
if #groups > 0 then
|
||||
if next(grouped_ingredients) ~= nil then
|
||||
local take
|
||||
for itemname, count in pairs(inv_index) do
|
||||
if count > 0 then
|
||||
local def = minetest.registered_items[itemname]
|
||||
local item_groups = def and def.groups or {}
|
||||
for i = 1, #groups do
|
||||
local group = groups[i]
|
||||
local groupname = "group:" .. group
|
||||
if item_groups[group] and item_groups[group] >= 1
|
||||
and consumption_with_groups[groupname] > 0
|
||||
-- groupname is the string as defined by recipe.
|
||||
-- e.g. group:dye,color_blue
|
||||
-- groups holds the group names split into a list
|
||||
-- ready to be passed to core.get_item_group()
|
||||
for groupname, groups in pairs(grouped_ingredients) do
|
||||
if consumption_with_groups[groupname] > 0
|
||||
and ingredient_groups_match_item(groups, itemname)
|
||||
then
|
||||
take = math.min(count, consumption_with_groups[groupname])
|
||||
take = math.min(count,
|
||||
consumption_with_groups[groupname])
|
||||
consumption_with_groups[groupname] =
|
||||
consumption_with_groups[groupname] - take
|
||||
consumption_with_groups[groupname] - take
|
||||
|
||||
assert(consumption_with_groups[groupname] >= 0)
|
||||
consumption[itemname] =
|
||||
(consumption[itemname] or 0) + take
|
||||
(consumption[itemname] or 0) + take
|
||||
|
||||
inv_index[itemname] = inv_index[itemname] - take
|
||||
inv_index[itemname] =
|
||||
inv_index[itemname] - take
|
||||
assert(inv_index[itemname] >= 0)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user