Skip to content

Commit

Permalink
Merge branch 'master' into luacheck-builtin-std
Browse files Browse the repository at this point in the history
  • Loading branch information
BuckarooBanzay authored Jun 18, 2024
2 parents 69bd905 + 71fe600 commit 5366e23
Show file tree
Hide file tree
Showing 41 changed files with 892 additions and 1,240 deletions.
3 changes: 2 additions & 1 deletion .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ read_globals = {
-- mods
"default", "mesecon", "digiline",
"screwdriver", "unified_inventory",
"i3", "mcl_experience", "awards"
"i3", "mcl_experience", "awards",
"xcompat", "fakelib"
}
66 changes: 46 additions & 20 deletions autocrafter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -433,6 +458,7 @@ minetest.register_node("pipeworks:autocrafter", {
drawtype = "normal",
tiles = {"pipeworks_autocrafter.png"},
groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1, dig_generic = 1, axey=1, handy=1, pickaxey=1},
is_ground_content = false,
_mcl_hardness=0.8,
tube = {insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
Expand Down
6 changes: 3 additions & 3 deletions autoplace_tubes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ local function nodeside(node, tubedir)
end

local backdir = minetest.facedir_to_dir(node.param2)
local back = pipeworks.vector_dot(backdir, tubedir)
local back = vector.dot(backdir, tubedir)
if back == 1 then
return "back"
elseif back == -1 then
return "front"
end

local topdir = pipeworks.facedir_to_top_dir(node.param2)
local top = pipeworks.vector_dot(topdir, tubedir)
local top = vector.dot(topdir, tubedir)
if top == 1 then
return "top"
elseif top == -1 then
return "bottom"
end

local rightdir = pipeworks.facedir_to_right_dir(node.param2)
local right = pipeworks.vector_dot(rightdir, tubedir)
local right = vector.dot(rightdir, tubedir)
if right == 1 then
return "right"
else
Expand Down
5 changes: 5 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ Changelog



2024-02-26 (SwissalpS)
set is_ground_content to false for various nodes.



2023-06-22 (SwissalpS, rubenwardy)
groups support in recipe. Set recipe as usual via recipe formspec or digilines.
Autocrafter now resolves matching recipe using groups so that items in input
Expand Down
90 changes: 90 additions & 0 deletions chests.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
pipeworks.chests = {}

-- register a chest to connect with pipeworks tubes.
-- will autoconnect to tubes and add tube inlets to the textures
-- it is highly recommended to allow the user to change the "splitstacks" int (1 to enable) in the node meta
-- but that can't be done by this function

-- @param override: additional overrides, such as stuff to modify the node formspec
-- @param connect_sides: which directions the chests shall connect to
function pipeworks.override_chest(chestname, override, connect_sides)
local old_def = minetest.registered_nodes[chestname]

local tube_entry = "^pipeworks_tube_connection_wooden.png"
override.tiles = override.tiles or old_def.tiles
-- expand the tiles table if it has been shortened
if #override.tiles < 6 then
for i = #override.tiles, 6 do
override.tiles[i] = override.tiles[#override.tiles]
end
end
-- add inlets to the sides that connect to tubes
local tile_directions = {"top", "bottom", "right", "left", "back", "front"}
for i, direction in ipairs(tile_directions) do
if connect_sides[direction] then
if type(override.tiles[i]) == "string" then
override.tiles[i] = override.tiles[i] .. tube_entry
elseif type(override.tiles[i]) == "table" and not override.tiles[i].animation then
override.tiles[i].name = override.tiles[i].name .. tube_entry
end
end
end

local old_after_place_node = override.after_place_node or old_def.after_place_node or function() end
override.after_place_node = function(pos, placer, itemstack, pointed_thing)
old_after_place_node(pos, placer, itemstack, pointed_thing)
pipeworks.after_place(pos)
end

local old_after_dig = override.after_dig or old_def.after_dig or function() end
override.after_dig_node = function(pos, oldnode, oldmetadata, digger)
old_after_dig(pos, oldnode, oldmetadata, digger)
pipeworks.after_dig(pos, oldnode, oldmetadata, digger)
end

local old_on_rotate
if override.on_rotate ~= nil then
old_on_rotate = override.on_rotate
elseif old_def.on_rotate ~= nil then
old_on_rotate = old_def.on_rotate
else
old_on_rotate = function() end
end
-- on_rotate = false -> rotation disabled, no need to update tubes
-- everything else: undefined by the most common screwdriver mods
if type(old_on_rotate) == "function" then
override.on_rotate = function(pos, node, user, mode, new_param2)
if old_on_rotate(pos, node, user, mode, new_param2) ~= false then
return pipeworks.on_rotate(pos, node, user, mode, new_param2)
else
return false
end
end
end

override.tube = {
insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:add_item("main", stack)
end,
can_insert = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if meta:get_int("splitstacks") == 1 then
stack = stack:peek_item(1)
end
return inv:room_for_item("main", stack)
end,
input_inventory = "main",
connect_sides = connect_sides
}

-- Add the extra groups
override.groups = override.groups or old_def.groups or {}
override.groups.tubedevice = 1
override.groups.tubedevice_receiver = 1

minetest.override_item(chestname, override)
pipeworks.chests[chestname] = true
end
Loading

0 comments on commit 5366e23

Please sign in to comment.