forked from VoxeLibre/VoxeLibre
Make hoppers work with all containers
... by massively simplifying the ABM code and using mcl_util code
This commit is contained in:
parent
77c458e4fa
commit
b946ad3cef
|
@ -160,155 +160,24 @@ minetest.register_abm({
|
||||||
interval = 1.0,
|
interval = 1.0,
|
||||||
chance = 1,
|
chance = 1,
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
|
-- Get node pos' for item transfer
|
||||||
|
local uppos = {x=pos.x,y=pos.y+1,z=pos.z}
|
||||||
|
local downpos = {x=pos.x,y=pos.y-1,z=pos.z}
|
||||||
|
|
||||||
local min = {x=pos.x-1,y=pos.y-1,z=pos.z-1}
|
-- Move an item from the hopper into container below
|
||||||
local max = {x=pos.x+1,y=pos.y+1,z=pos.z+1}
|
mcl_util.move_item_container(pos, "main", -1, downpos)
|
||||||
local vm = minetest.get_voxel_manip()
|
|
||||||
local emin, emax = vm:read_from_map(min,max)
|
|
||||||
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
|
||||||
local data = vm:get_data()
|
|
||||||
|
|
||||||
local a = vm:get_node_at({x=pos.x,y=pos.y-1,z=pos.z}).name
|
-- Suck an item from the container above into the hopper
|
||||||
local b = vm:get_node_at({x=pos.x,y=pos.y+1,z=pos.z}).name
|
local upnode = minetest.get_node(uppos)
|
||||||
local ag = minetest.get_node_group(a, "shulker_box")
|
local g = minetest.registered_nodes[upnode.name].groups.container
|
||||||
local bg = minetest.get_node_group(b, "shulker_box")
|
if g == 2 or g == 3 then
|
||||||
local ashulker = not (ag == 0 or ag == nil)
|
-- Typical container inventory
|
||||||
local bshulker = not (bg == 0 or bg == nil)
|
mcl_util.move_item_container(uppos, "main", -1, pos)
|
||||||
|
elseif g == 4 then
|
||||||
--the mcl_hoppers input
|
-- Furnace output
|
||||||
if b == "mcl_chests:chest" or b == "mcl_chests:chest_left" or b == "mcl_chests:chest_right" or bshulker or b == "mcl_hoppers:hopper" or b == "mcl_hoppers:hopper_side" then
|
mcl_util.move_item_container(uppos, "dst", -1, pos)
|
||||||
--mcl_hoppers inventory
|
|
||||||
local meta = minetest.get_meta(pos);
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local invsize = inv:get_size("main")
|
|
||||||
|
|
||||||
--chest/mcl_hoppers/furnace inventory
|
|
||||||
local meta2 = minetest.get_meta({x=pos.x,y=pos.y+1,z=pos.z});
|
|
||||||
local inv2 = meta2:get_inventory()
|
|
||||||
local invsize2 = inv2:get_size("main")
|
|
||||||
if inv2:is_empty("main") == false then
|
|
||||||
for i = 1,invsize2 do
|
|
||||||
local stack = inv2:get_stack("main", i)
|
|
||||||
local item = stack:get_name()
|
|
||||||
if item ~= "" then
|
|
||||||
if inv:room_for_item("main", item) == false then
|
|
||||||
--print("no room for items 2")
|
|
||||||
--return
|
|
||||||
end
|
|
||||||
--print(stack:to_string())
|
|
||||||
stack:take_item(1)
|
|
||||||
inv2:set_stack("main", i, stack)
|
|
||||||
--add to mcl_hoppers
|
|
||||||
--print("adding item")
|
|
||||||
inv:add_item("main", item)
|
|
||||||
break
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if b == "mcl_furnaces:furnace" or b == "mcl_furnaces:furnace_active" then
|
|
||||||
--mcl_hoppers inventory
|
|
||||||
local meta = minetest.get_meta(pos);
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local invsize = inv:get_size("main")
|
|
||||||
|
|
||||||
--chest/mcl_hoppers/furnace inventory
|
|
||||||
local meta2 = minetest.get_meta({x=pos.x,y=pos.y+1,z=pos.z});
|
|
||||||
local inv2 = meta2:get_inventory()
|
|
||||||
local invsize2 = inv2:get_size("dst")
|
|
||||||
if inv2:is_empty("dst") == false then
|
|
||||||
|
|
||||||
for i = 1,invsize2 do
|
|
||||||
local stack = inv2:get_stack("dst", i)
|
|
||||||
local item = stack:get_name()
|
|
||||||
if item ~= "" then
|
|
||||||
if inv:room_for_item("main", item) == false then
|
|
||||||
--print("no room for items")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
--print(stack:to_string())
|
|
||||||
stack:take_item(1)
|
|
||||||
inv2:set_stack("dst", i, stack)
|
|
||||||
--add to mcl_hoppers
|
|
||||||
--print("adding item")
|
|
||||||
inv:add_item("main", item)
|
|
||||||
break
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--the mcl_hoppers output
|
|
||||||
if a == "mcl_chests:chest" or a == "mcl_chests:chest_left" or a == "mcl_chests:chest_right" or ashulker or a == "mcl_hoppers:hopper" or a == "mcl_hoppers:hopper_side" then
|
|
||||||
--mcl_hoppers inventory
|
|
||||||
local meta = minetest.get_meta(pos);
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
if inv:is_empty("main") == true then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local invsize = inv:get_size("main")
|
|
||||||
|
|
||||||
--chest/mcl_hoppers/furnace inventory
|
|
||||||
local meta2 = minetest.get_meta({x=pos.x,y=pos.y-1,z=pos.z});
|
|
||||||
local inv2 = meta2:get_inventory()
|
|
||||||
local invsize2 = inv2:get_size("main")
|
|
||||||
|
|
||||||
for i = 1,invsize do
|
|
||||||
local stack = inv:get_stack("main", i)
|
|
||||||
local item = stack:get_name()
|
|
||||||
if item ~= "" then
|
|
||||||
if inv2:room_for_item("main", item) == false then
|
|
||||||
--print("no room for items")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
stack:take_item(1)
|
|
||||||
inv:set_stack("main", i, stack)
|
|
||||||
--add to mcl_hoppers or chest
|
|
||||||
--print("adding item")
|
|
||||||
inv2:add_item("main", item)
|
|
||||||
break
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--print(inv)
|
|
||||||
elseif a == "mcl_furnaces:furnace" or a == "mcl_furnaces:furnace_active" then
|
|
||||||
--print("test")
|
|
||||||
--room_for_item(listname, stack)
|
|
||||||
--mcl_hoppers inventory
|
|
||||||
local meta = minetest.get_meta(pos);
|
|
||||||
--print(dump(meta:to_table()))
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
if inv:is_empty("main") == true then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local invsize = inv:get_size("main")
|
|
||||||
|
|
||||||
--chest/mcl_hoppers/furnace inventory
|
|
||||||
local meta2 = minetest.get_meta({x=pos.x,y=pos.y-1,z=pos.z});
|
|
||||||
local inv2 = meta2:get_inventory()
|
|
||||||
local invsize2 = inv2:get_size("src")
|
|
||||||
|
|
||||||
for i = 1,invsize do
|
|
||||||
local stack = inv:get_stack("main", i)
|
|
||||||
local item = stack:get_name()
|
|
||||||
if item ~= "" then
|
|
||||||
if inv2:room_for_item("src", item) == false then
|
|
||||||
--print("no room for items")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
minetest.get_node_timer({x=pos.x,y=pos.y-1,z=pos.z}):start(1.0)
|
|
||||||
stack:take_item(1)
|
|
||||||
inv:set_stack("main", i, stack)
|
|
||||||
--add to mcl_hoppers or chest
|
|
||||||
--print("adding item")
|
|
||||||
inv2:add_item("src", item)
|
|
||||||
break
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -319,16 +188,9 @@ minetest.register_abm({
|
||||||
interval = 1.0,
|
interval = 1.0,
|
||||||
chance = 1,
|
chance = 1,
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
|
-- Determine to which side the hopper is facing, get nodes
|
||||||
local min = {x=pos.x-1,y=pos.y-1,z=pos.z-1}
|
local face = minetest.get_node(pos).param2
|
||||||
local max = {x=pos.x+1,y=pos.y+1,z=pos.z+1}
|
|
||||||
local vm = minetest.get_voxel_manip()
|
|
||||||
local emin, emax = vm:read_from_map(min,max)
|
|
||||||
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
|
||||||
local data = vm:get_data()
|
|
||||||
local face = vm:get_node_at(pos).param2
|
|
||||||
local front = {}
|
local front = {}
|
||||||
--print(face)
|
|
||||||
if face == 0 then
|
if face == 0 then
|
||||||
front = {x=pos.x-1,y=pos.y,z=pos.z}
|
front = {x=pos.x-1,y=pos.y,z=pos.z}
|
||||||
elseif face == 1 then
|
elseif face == 1 then
|
||||||
|
@ -338,150 +200,24 @@ minetest.register_abm({
|
||||||
elseif face == 3 then
|
elseif face == 3 then
|
||||||
front = {x=pos.x,y=pos.y,z=pos.z-1}
|
front = {x=pos.x,y=pos.y,z=pos.z-1}
|
||||||
end
|
end
|
||||||
local a = vm:get_node_at(front).name
|
local above = {x=pos.x,y=pos.y+1,z=pos.z}
|
||||||
local b = vm:get_node_at({x=pos.x,y=pos.y+1,z=pos.z}).name
|
|
||||||
local ag = minetest.get_node_group(a, "shulker_box")
|
|
||||||
local bg = minetest.get_node_group(b, "shulker_box")
|
|
||||||
local ashulker = not (ag == 0 or ag == nil)
|
|
||||||
local bshulker = not (bg == 0 or bg == nil)
|
|
||||||
|
|
||||||
--the mcl_hoppers input
|
local frontnode = minetest.get_node(front)
|
||||||
if b == "mcl_chests:chest" or b == "mcl_chests:chest_left" or b == "mcl_chests:chest_right" or bshulker or b == "mcl_hoppers:hopper" or b == "mcl_hoppers:hopper_side" then
|
|
||||||
--mcl_hoppers inventory
|
|
||||||
local meta = minetest.get_meta(pos);
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local invsize = inv:get_size("main")
|
|
||||||
|
|
||||||
--chest/mcl_hoppers/furnace inventory
|
-- Move an item from the hopper into the container to which the hopper points to
|
||||||
local meta2 = minetest.get_meta({x=pos.x,y=pos.y+1,z=pos.z});
|
mcl_util.move_item_container(pos, "main", -1, front)
|
||||||
local inv2 = meta2:get_inventory()
|
|
||||||
local invsize2 = inv2:get_size("main")
|
|
||||||
if inv2:is_empty("main") == false then
|
|
||||||
for i = 1,invsize2 do
|
|
||||||
local stack = inv2:get_stack("main", i)
|
|
||||||
local item = stack:get_name()
|
|
||||||
if item ~= "" then
|
|
||||||
if inv:room_for_item("main", item) == false then
|
|
||||||
--print("no room for items 2")
|
|
||||||
--return
|
|
||||||
end
|
|
||||||
--print(stack:to_string())
|
|
||||||
stack:take_item(1)
|
|
||||||
inv2:set_stack("main", i, stack)
|
|
||||||
--add to mcl_hoppers
|
|
||||||
--print("adding item")
|
|
||||||
inv:add_item("main", item)
|
|
||||||
break
|
|
||||||
|
|
||||||
|
-- Suck an item from the container above into the hopper
|
||||||
|
local abovenode = minetest.get_node(above)
|
||||||
|
local g = minetest.registered_nodes[abovenode.name].groups.container
|
||||||
|
if g == 2 or g == 3 then
|
||||||
|
-- Typical container inventory
|
||||||
|
mcl_util.move_item_container(above, "main", -1, pos)
|
||||||
|
elseif g == 4 then
|
||||||
|
-- Furnace output
|
||||||
|
mcl_util.move_item_container(above, "dst", -1, pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
if b == "mcl_furnaces:furnace" or b == "mcl_furnaces:furnace_active" then
|
|
||||||
--mcl_hoppers inventory
|
|
||||||
local meta = minetest.get_meta(pos);
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local invsize = inv:get_size("main")
|
|
||||||
|
|
||||||
--chest/mcl_hoppers/furnace inventory
|
|
||||||
local meta2 = minetest.get_meta({x=pos.x,y=pos.y+1,z=pos.z});
|
|
||||||
local inv2 = meta2:get_inventory()
|
|
||||||
local invsize2 = inv2:get_size("dst")
|
|
||||||
if inv2:is_empty("dst") == false then
|
|
||||||
for i = 1,invsize2 do
|
|
||||||
local stack = inv2:get_stack("dst", i)
|
|
||||||
local item = stack:get_name()
|
|
||||||
if item ~= "" then
|
|
||||||
if inv:room_for_item("main", item) == false then
|
|
||||||
--print("no room for items")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
--print(stack:to_string())
|
|
||||||
stack:take_item(1)
|
|
||||||
inv2:set_stack("dst", i, stack)
|
|
||||||
--add to mcl_hoppers
|
|
||||||
--print("adding item")
|
|
||||||
inv:add_item("main", item)
|
|
||||||
break
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--the mcl_hoppers output
|
|
||||||
if a == "mcl_chests:chest" or a == "mcl_chests:chest_left" or "mcl_chests:chest_right" or ashulker or a == "mcl_hoppers:hopper" or a == "mcl_hoppers:hopper_side" then
|
|
||||||
--print("test")
|
|
||||||
--room_for_item(listname, stack)
|
|
||||||
--mcl_hoppers inventory
|
|
||||||
local meta = minetest.get_meta(pos);
|
|
||||||
--print(dump(meta:to_table()))
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
if inv:is_empty("main") == true then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local invsize = inv:get_size("main")
|
|
||||||
|
|
||||||
--chest/mcl_hoppers/furnace inventory
|
|
||||||
local meta2 = minetest.get_meta(front);
|
|
||||||
local inv2 = meta2:get_inventory()
|
|
||||||
local invsize2 = inv2:get_size("main")
|
|
||||||
|
|
||||||
for i = 1,invsize do
|
|
||||||
local stack = inv:get_stack("main", i)
|
|
||||||
local item = stack:get_name()
|
|
||||||
if item ~= "" then
|
|
||||||
if inv2:room_for_item("main", item) == false then
|
|
||||||
--print("no room for items")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
stack:take_item(1)
|
|
||||||
inv:set_stack("main", i, stack)
|
|
||||||
--add to mcl_hoppers or chest
|
|
||||||
--print("adding item")
|
|
||||||
inv2:add_item("main", item)
|
|
||||||
break
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--print(inv)
|
|
||||||
elseif a == "mcl_furnaces:furnace" or a == "mcl_furnaces:furnace_active" then
|
|
||||||
--print("test")
|
|
||||||
--room_for_item(listname, stack)
|
|
||||||
--mcl_hoppers inventory
|
|
||||||
local meta = minetest.get_meta(pos);
|
|
||||||
--print(dump(meta:to_table()))
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
if inv:is_empty("main") == true then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local invsize = inv:get_size("main")
|
|
||||||
|
|
||||||
--chest/mcl_hoppers/furnace inventory
|
|
||||||
local meta2 = minetest.get_meta(front);
|
|
||||||
local inv2 = meta2:get_inventory()
|
|
||||||
local invsize2 = inv2:get_size("fuel")
|
|
||||||
|
|
||||||
for i = 1,invsize do
|
|
||||||
local stack = inv:get_stack("main", i)
|
|
||||||
local item = stack:get_name()
|
|
||||||
if item ~= "" then
|
|
||||||
if inv2:room_for_item("fuel", item) == false then
|
|
||||||
--print("no room for items")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
stack:take_item(1)
|
|
||||||
inv:set_stack("main", i, stack)
|
|
||||||
--add to mcl_hoppers or chest
|
|
||||||
--print("adding item")
|
|
||||||
minetest.get_node_timer(front):start(1.0)
|
|
||||||
inv2:add_item("fuel", item)
|
|
||||||
break
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craftitem("mcl_hoppers:hopper_item", {
|
minetest.register_craftitem("mcl_hoppers:hopper_item", {
|
||||||
|
|
|
@ -100,13 +100,20 @@ end
|
||||||
-- Moves a single item from one inventory to another
|
-- Moves a single item from one inventory to another
|
||||||
--- source_inventory: Inventory to take the item from
|
--- source_inventory: Inventory to take the item from
|
||||||
--- source_list: List name of the source inventory from which to take the item
|
--- source_list: List name of the source inventory from which to take the item
|
||||||
--- source_stack_id: The inventory position ID of the source inventory to take the item from
|
--- source_stack_id: The inventory position ID of the source inventory to take the item from (-1 for first occupied slot)
|
||||||
--- destination_inventory: Put item into this inventory
|
--- destination_inventory: Put item into this inventory
|
||||||
--- destination_list: List name of the destination inventory to which to put the item into
|
--- destination_list: List name of the destination inventory to which to put the item into
|
||||||
|
|
||||||
-- Returns true on success and false on failure
|
-- Returns true on success and false on failure
|
||||||
-- Possible failures: No item in source slot, destination inventory full
|
-- Possible failures: No item in source slot, destination inventory full
|
||||||
function mcl_util.move_item(source_inventory, source_list, source_stack_id, destination_inventory, destination_list)
|
function mcl_util.move_item(source_inventory, source_list, source_stack_id, destination_inventory, destination_list)
|
||||||
|
if source_stack_id == -1 then
|
||||||
|
source_stack_id = mcl_util.get_first_occupied_inventory_slot(source_inventory, source_list)
|
||||||
|
if source_stack_id == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if not source_inventory:is_empty(source_list) then
|
if not source_inventory:is_empty(source_list) then
|
||||||
local stack = source_inventory:get_stack(source_list, source_stack_id)
|
local stack = source_inventory:get_stack(source_list, source_stack_id)
|
||||||
local item = stack:get_name()
|
local item = stack:get_name()
|
||||||
|
@ -126,7 +133,7 @@ end
|
||||||
-- Moves a single item from one container node into another.
|
-- Moves a single item from one container node into another.
|
||||||
--- source_pos: Position ({x,y,z}) of the node to take the item from
|
--- source_pos: Position ({x,y,z}) of the node to take the item from
|
||||||
--- source_list: List name of the source inventory from which to take the item
|
--- source_list: List name of the source inventory from which to take the item
|
||||||
--- source_stack_id: The inventory position ID of the source inventory to take the item from
|
--- source_stack_id: The inventory position ID of the source inventory to take the item from (-1 for first occupied slot)
|
||||||
--- destination_pos: Position ({x,y,z}) of the node to put the item into
|
--- destination_pos: Position ({x,y,z}) of the node to put the item into
|
||||||
-- Returns true on success and false on failure
|
-- Returns true on success and false on failure
|
||||||
function mcl_util.move_item_container(source_pos, source_list, source_stack_id, destination_pos)
|
function mcl_util.move_item_container(source_pos, source_list, source_stack_id, destination_pos)
|
||||||
|
@ -139,6 +146,13 @@ function mcl_util.move_item_container(source_pos, source_list, source_stack_id,
|
||||||
local snodedef = minetest.registered_nodes[minetest.get_node(source_pos).name]
|
local snodedef = minetest.registered_nodes[minetest.get_node(source_pos).name]
|
||||||
local dnodedef = minetest.registered_nodes[minetest.get_node(destination_pos).name]
|
local dnodedef = minetest.registered_nodes[minetest.get_node(destination_pos).name]
|
||||||
|
|
||||||
|
if source_stack_id == -1 then
|
||||||
|
source_stack_id = mcl_util.get_first_occupied_inventory_slot(sinv, source_list)
|
||||||
|
if source_stack_id == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- If it's a container, put it into the container
|
-- If it's a container, put it into the container
|
||||||
if dnodedef.groups.container then
|
if dnodedef.groups.container then
|
||||||
if dnodedef.groups.container == 2 or snodedef.groups.continer == 3 then
|
if dnodedef.groups.container == 2 or snodedef.groups.continer == 3 then
|
||||||
|
@ -154,3 +168,15 @@ function mcl_util.move_item_container(source_pos, source_list, source_stack_id,
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Returns the ID of the first non-empty slot in the given inventory list
|
||||||
|
-- or nil, if inventory is empty.
|
||||||
|
function mcl_util.get_first_occupied_inventory_slot(inventory, listname)
|
||||||
|
for i=1, inventory:get_size(listname) do
|
||||||
|
local stack = inventory:get_stack(listname, i)
|
||||||
|
if not stack:is_empty() then
|
||||||
|
return i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue