From 450e26b574da25f3176f234c9680fab1085ecd8e Mon Sep 17 00:00:00 2001 From: gpn39f Date: Fri, 20 Sep 2019 14:23:14 +0200 Subject: [PATCH 1/4] add new function get_inv_items_from_slot the base function does twice.. store the items from the given slot and when this fails store a other slot searched from 1-8. this behavior is unwanted for the robot. The new function store only num or slot.max_count items from the given slot --- cmd_item.lua | 6 +++--- lib.lua | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/cmd_item.lua b/cmd_item.lua index df54289..4172966 100644 --- a/cmd_item.lua +++ b/cmd_item.lua @@ -58,7 +58,7 @@ 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 +85,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 +131,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) diff --git a/lib.lua b/lib.lua index 7d0dfb9..099f999 100644 --- a/lib.lua +++ b/lib.lua @@ -178,6 +178,28 @@ 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 +function signs_bot.lib.get_inv_items_from_slot(src_inv, src_list, slot, num) + if slot < 1 or slot > 8 or num < 1 then + return + end + local to_take = num + local stack = src_inv:get_stack(src_list, slot) + local item_count = stack:get_count() + if item_count == 0 then + -- there is no item in slot, so we leave + return + elseif item_count >= num then + -- the slot has enough items + else + -- the slot has fewer items as needed + to_take = item_count + 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) From e904b56c9baa00248c7994ed1610a0de04b45133 Mon Sep 17 00:00:00 2001 From: gpn39f Date: Fri, 20 Sep 2019 15:49:25 +0200 Subject: [PATCH 2/4] build slot max_count from inventory size --- lib.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib.lua b/lib.lua index 099f999..9a240cd 100644 --- a/lib.lua +++ b/lib.lua @@ -178,9 +178,10 @@ 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 +-- 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) - if slot < 1 or slot > 8 or num < 1 then + local max_count = src_inv:get_size(src_list) + if slot < 1 or slot > max_count or num < 1 then return end local to_take = num From bee2b4ecc4071640d16a448f3aa69d2d65cfec2e Mon Sep 17 00:00:00 2001 From: gpn39f Date: Sat, 21 Sep 2019 02:39:33 +0200 Subject: [PATCH 3/4] append the command item_add for negative num this allow to define a "bool item_leave_one" when using the num as negative value. using negative num will leave one item in used robot slot --- cmd_item.lua | 2 +- lib.lua | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cmd_item.lua b/cmd_item.lua index 4172966..83d073c 100644 --- a/cmd_item.lua +++ b/cmd_item.lua @@ -205,7 +205,7 @@ signs_bot.register_botcommand("add_item", { " 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) diff --git a/lib.lua b/lib.lua index 9a240cd..9eadcd4 100644 --- a/lib.lua +++ b/lib.lua @@ -180,22 +180,23 @@ 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 max_count = src_inv:get_size(src_list) - if slot < 1 or slot > max_count or num < 1 then - return - end - local to_take = 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 >= num then + 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 end + to_take = to_take - item_leave_one local taken = stack:take_item(to_take) src_inv:set_stack(src_list, slot, stack) return taken From 076ea2622e115a3e6eb8322ff678d8e7076bec71 Mon Sep 17 00:00:00 2001 From: gpn39f Date: Sat, 21 Sep 2019 10:52:23 +0200 Subject: [PATCH 4/4] replace the logic of the function: robot_take now the command take_item will not use "any slot" from chest to load items. now the function determine first the item of the given robot slot. then he search in chest only for the same items it's found. --- cmd_item.lua | 74 ++++++++++++++++++++++++++++++++++++++++++---------- lib.lua | 17 ++++++++++-- 2 files changed, 75 insertions(+), 16 deletions(-) diff --git a/cmd_item.lua b/cmd_item.lua index 83d073c..299d38b 100644 --- a/cmd_item.lua +++ b/cmd_item.lua @@ -31,28 +31,74 @@ 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 @@ -156,7 +202,7 @@ signs_bot.register_botcommand("take_item", { " 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) diff --git a/lib.lua b/lib.lua index 9eadcd4..254a9de 100644 --- a/lib.lua +++ b/lib.lua @@ -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 @@ -194,9 +208,8 @@ function signs_bot.lib.get_inv_items_from_slot(src_inv, src_list, slot, num) -- the slot has enough items else -- the slot has fewer items as needed - to_take = item_count + to_take = item_count - item_leave_one end - to_take = to_take - item_leave_one local taken = stack:take_item(to_take) src_inv:set_stack(src_list, slot, stack) return taken