Merge pull request #1 from gpn39f/master

add new function get_inv_items_from_slot
This commit is contained in:
Joachim Stolberg 2019-09-23 21:27:54 +02:00 committed by GitHub
commit 4bbeec18ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 101 additions and 18 deletions

View File

@ -31,34 +31,80 @@ local RegisteredInventories = {
-- Move from/to inventories
--
-- From chest to robot
function signs_bot.robot_take(base_pos, robot_pos, param2, want_count, slot)
local target_pos = lib.next_pos(robot_pos, param2)
local node = lib.get_node_lvm(target_pos)
local def = RegisteredInventories[node.name]
function signs_bot.robot_take(base_pos, robot_pos, param2, num, slot)
-- find parameter from the chest
local target_pos = lib.next_pos(robot_pos, param2)
local node = lib.get_node_lvm(target_pos)
local def = RegisteredInventories[node.name]
local src_inv = minetest.get_inventory({type="node", pos=target_pos})
if not src_inv then
return
end
-- find parameter from robot
local dst_inv = minetest.get_inventory({type="node", pos=base_pos})
if not dst_inv then
return
end
local dst_stack = dst_inv:get_stack("main", slot)
local dst_max_item_count = dst_stack:get_count()
local dst_item_name = dst_stack:get_name()
if not dst_item_name then
return
end
-- check for negative num
local want_count = math.abs(num)
local item_leave_one = 0
if num < 0 then
item_leave_one = 1
end
-- check for robot has enough items, no more items needed
if dst_max_item_count >= want_count then
return
end
local owner = M(base_pos):get_string("owner")
local taken
local to_take_left = want_count
if def and (not def.allow_take or def.allow_take(target_pos, nil, owner)) then
local src_inv = minetest.get_inventory({type="node", pos=target_pos})
taken = lib.get_inv_items(src_inv, def.take_listname, 1, want_count)
while to_take_left > 0 do
-- find first slot in chest with has correct item, and get his parameter
local src_slot = lib.find_inv_slot(src_inv, "main", dst_item_name)
if not src_slot or src_slot == 0 then
break
end
local src_stack = src_inv:get_stack("main", src_slot)
local src_max_item_count = src_stack:get_count()
local to_take = to_take_left
if src_max_item_count >= (to_take + item_leave_one) then
-- the slot has enough items
else
-- the slot has fewer items as needed
to_take = src_max_item_count - item_leave_one
end
local taken = lib.get_inv_items_from_slot(src_inv, def.take_listname, src_slot, to_take)
lib.put_inv_items(dst_inv, "main", slot, taken)
to_take_left = to_take_left - to_take
end
elseif NODE_IO then
local side = node_io.get_target_side(robot_pos, target_pos)
local fake_player = lib.fake_player(owner)
taken = node_io.take_item(target_pos, node, side, fake_player, nil, want_count)
lib.drop_items(robot_pos, taken)
else
return
end
if taken then
local dst_inv = minetest.get_inventory({type="node", pos=base_pos})
if not lib.put_inv_items(dst_inv, "main", slot, taken) then
lib.drop_items(robot_pos, taken)
end
end
end
-- From robot to chest
function signs_bot.robot_put(base_pos, robot_pos, param2, num, slot)
local src_inv = minetest.get_inventory({type="node", pos=base_pos})
local taken = lib.get_inv_items(src_inv, "main", slot, num)
local taken = lib.get_inv_items_from_slot(src_inv, "main", slot, num)
if taken then
local target_pos = lib.next_pos(robot_pos, param2)
local node = lib.get_node_lvm(target_pos)
@ -85,7 +131,7 @@ end
-- From robot to furnace
function signs_bot.robot_put_fuel(base_pos, robot_pos, param2, num, slot)
local src_inv = minetest.get_inventory({type="node", pos=base_pos})
local taken = lib.get_inv_items(src_inv, "main", slot, num)
local taken = lib.get_inv_items_from_slot(src_inv, "main", slot, num)
if taken then
local target_pos = lib.next_pos(robot_pos, param2)
local node = lib.get_node_lvm(target_pos)
@ -131,7 +177,7 @@ end
-- From robot to chest
function signs_bot.robot_put_cond(base_pos, robot_pos, param2, num, slot)
local src_inv = minetest.get_inventory({type="node", pos=base_pos})
local taken = lib.get_inv_items(src_inv, "main", slot, num)
local taken = lib.get_inv_items_from_slot(src_inv, "main", slot, num)
if taken then
local target_pos = lib.next_pos(robot_pos, param2)
local node = lib.get_node_lvm(target_pos)
@ -156,7 +202,7 @@ signs_bot.register_botcommand("take_item", {
"<slot> is the inventory slot (1..8)"),
check = function(num, slot)
num = tonumber(num or 1)
if not num or num < 1 or num > 99 then
if not num or num == 0 or num < -99 or num > 99 then
return false
end
slot = tonumber(slot or 1)
@ -205,7 +251,7 @@ signs_bot.register_botcommand("add_item", {
"<slot> is the inventory slot (1..8)"),
check = function(num, slot)
num = tonumber(num or 1)
if not num or num < 1 or num > 99 then
if not num or num == 0 or num < -99 or num > 99 then
return false
end
slot = tonumber(slot or 1)

37
lib.lua
View File

@ -59,6 +59,20 @@ function signs_bot.lib.dest_pos(pos, param2, route)
return pos, p2
end
function signs_bot.lib.find_inv_slot(src_inv, src_list, item_name)
if not item_name then
return
end
for idx = 1, src_inv:get_size(src_list) do
local stack = src_inv:get_stack(src_list, idx)
if stack:get_count() > 1 then
if stack:get_name() == item_name then
return idx
end
end
end
end
function signs_bot.lib.get_node_lvm(pos)
local node = minetest.get_node_or_nil(pos)
if node then
@ -178,6 +192,29 @@ function signs_bot.lib.get_inv_items(src_inv, src_list, slot, num)
end
end
-- use only the given slot and return num (or count) items from this slot
function signs_bot.lib.get_inv_items_from_slot(src_inv, src_list, slot, num)
local to_take = math.abs(num)
local stack = src_inv:get_stack(src_list, slot)
local item_count = stack:get_count()
local item_leave_one = 0
if num < 0 then
item_leave_one = 1
end
if item_count == 0 then
-- there is no item in slot, so we leave
return
elseif item_count >= (to_take + item_leave_one) then
-- the slot has enough items
else
-- the slot has fewer items as needed
to_take = item_count - item_leave_one
end
local taken = stack:take_item(to_take)
src_inv:set_stack(src_list, slot, stack)
return taken
end
function signs_bot.lib.get_inv_items_cond(src_inv, src_list, slot, num)
for idx = (slot or 1),src_inv:get_size(src_list) do
local stack = src_inv:get_stack(src_list, idx)