From 2db5040c5211adc3597045b11e22e08e096fa45b Mon Sep 17 00:00:00 2001 From: D4VID Date: Sun, 6 Oct 2024 18:38:37 +0200 Subject: [PATCH] Specify item damage --- craft.lua | 104 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 28 deletions(-) diff --git a/craft.lua b/craft.lua index fa7b87a..59ba4b2 100644 --- a/craft.lua +++ b/craft.lua @@ -9,39 +9,64 @@ RESULT_SLOT = 4 local iron_pickaxe_recipe = { result = { - name = 'minecraft:iron_pickaxe', + item = { 'minecraft:iron_pickaxe', 0 }, count = 1, }, ingredients = { - 'minecraft:iron_ingot', 'minecraft:iron_ingot', 'minecraft:iron_ingot', - nil, 'minecraft:stick', nil, - nil, 'minecraft:stick', nil, + -- pair of name (string id) and damage separated by ';' + 'minecraft:iron_ingot;0', 'minecraft:iron_ingot;0', 'minecraft:iron_ingot;0', + nil, 'minecraft:stick;0', nil, + nil, 'minecraft:stick;0', nil, } } -- robots inventory is 4 wide and crafting uses the top left portion local slot_map = { - 1,2,3, - 5,6,7, - 9,10,11 + 1, 2, 3, + 5, 6, 7, + 9, 10, 11 } --- local function read_chest_contents() --- local size = inventory.getInventorySize(sides.forward) --- for slot = 1, size do --- local stack = inventory.getStackInSlot(sides.forward, slot) --- if stack then --- if stack.name == item then --- inventory.suckFromSlot(sides.forward, slot, 1) --- return true --- end --- end --- end --- end +---"item" being pair string id and damage separated by ';' eg. "minecraft:wool;3" +---returns "minecraft:wool", 3 +---@param str string +---@param delimiter string +---@return string|nil +---@return number|nil +local function parse_item(str, delimiter) + local pos = string.find(str, delimiter) + if not pos then + return nil,nil + end + return string.sub(str, 1, pos-1), tonumber(string.sub(str, pos+1)) +end + +---read the facing inventory and return a table of item names and their count or nil if not facing an inventory +---@return table|nil +local function read_chest_contents() + local contents = {} + local size = inventory.getInventorySize(sides.forward) + if not size then + return nil + end + for slot = 1, size do + local stack = inventory.getStackInSlot(sides.forward, slot) + if stack then + local name = stack.name .. ";" .. stack.damage + if contents[name] then + contents[name] = contents[name] + stack.size + else + contents[name] = stack.size + end + end + end + return contents +end --- store the item in the selected slot into the facing inventory +---store the item in the selected slot into the facing inventory +---@return boolean local function store_item() --- check if that item is present in the inventory + -- check if that item is present in the inventory local item = inventory.getStackInInternalSlot() local size = inventory.getInventorySize(sides.forward) @@ -82,9 +107,14 @@ local function store_item() end end --- Search the facing chest for "item" and take "count" items and place them in "slot" --- Returns number of items fetched +---Search the facing chest for "item" and take "count" items and place them in "slot" +---"item" being pair string id and damage separated by ';' eg. "minecraft:wool;3" +---Returns number of items fetched +---@param item string +---@param output_slot number +---@return boolean local function fetch_item(item, output_slot) + local name, damage = parse_item(item, ";") robot.select(output_slot) local size = inventory.getInventorySize(sides.forward) if not size then @@ -95,7 +125,7 @@ local function fetch_item(item, output_slot) for slot = 1, size do local stack = inventory.getStackInSlot(sides.forward, slot) if stack then - if stack.name == item then + if stack.name == name and stack.damage == damage then inventory.suckFromSlot(sides.forward, slot, 1) return true end @@ -106,8 +136,14 @@ local function fetch_item(item, output_slot) return false end --- accepts a recipe table containing result and ingredients +---accepts a recipe table containing result and ingredients +---@param recipe table +---@return boolean local function craft_recipe(recipe) + if inventory.getStackInInternalSlot(RESULT_SLOT) then + print('Cannot craft - output slot occupied') + return false + end for i, ingredient in pairs(recipe.ingredients) do print('Fetching ' .. ingredient) fetch_item(ingredient, slot_map[i]) @@ -118,10 +154,12 @@ local function craft_recipe(recipe) -- craft the resulting item local crafted = crafting.craft(1) - if not crafted then print('Crafting failed') + return false end + + return store_item() end -- local target = ... @@ -131,5 +169,15 @@ end -- return -- end --- craft_recipe(iron_pickaxe_recipe) -store_item() +craft_recipe(iron_pickaxe_recipe) + +-- store_item() + +-- local contents = read_chest_contents() +-- if contents then +-- for k,v in pairs(contents) do +-- print(k,v) +-- end +-- else +-- print('Not facing a chest') +-- end