From 1be0d4ce33b7db2b7e4bb0f8b4e8529280fdb2cc Mon Sep 17 00:00:00 2001 From: Christoph Urlacher Date: Tue, 7 Oct 2025 17:13:34 +0200 Subject: [PATCH] Implement testing for blocks in front/above/below the turtle so we don't mine chests --- controller/excavation_controller.lua | 2 +- controller/turtle_controller.lua | 55 ++++++++++++++++++++++++---- main.lua | 9 +++-- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/controller/excavation_controller.lua b/controller/excavation_controller.lua index 5081cd8..71a9a3f 100644 --- a/controller/excavation_controller.lua +++ b/controller/excavation_controller.lua @@ -246,7 +246,7 @@ function ExcavationController:Excavate() -- Finish up self.controller:MoveToPosition(0, 0, 0, self.controller.config.storage_direction) - self.controller:DropInventory() + self.controller:DropInventoryIntoChest() self.controller:TurnToDirection(Direction.NORTH) self.audio:StopPlaying() end diff --git a/controller/turtle_controller.lua b/controller/turtle_controller.lua index 8cd7589..18f5b63 100644 --- a/controller/turtle_controller.lua +++ b/controller/turtle_controller.lua @@ -102,15 +102,24 @@ function TurtleController:MoveForward(number_of_blocks, skip_unstocking, skip_re -- Mine/Move if self.mine_forward then while not turtle.forward() do + if self:TestForBlock("minecraft:chest") then + error("Won't mine because a chest is in the way!") + end turtle.dig() end elseif not turtle.forward() then error("Turtle failed to move forward!") end if self.mine_above then + if self:TestForBlock("minecraft:chest", true, false) then + error("Won't mine because a chest is in the way!") + end turtle.digUp() end if self.mine_below then + if self:TestForBlock("minecraft:chest", false, true) then + error("Won't mine because a chest is in the way!") + end turtle.digDown() end @@ -155,6 +164,9 @@ function TurtleController:MoveVertical(number_of_blocks, skip_unstocking, skip_r -- Mine/Move if mine_enabled then while not move_function() do + if self:TestForBlock("minecraft:chest", number_of_blocks > 0, number_of_blocks < 0) then + error("Won't mine because a chest is in the way!") + end mine_function() end elseif not move_function() then @@ -293,9 +305,24 @@ end ----------------------------------------------------------------------------------------------- ---@param block_name string +---@param above boolean | nil +---@param below boolean | nil ---@return boolean -function TurtleController:TestForBlock(block_name) - local has_block, block_data = turtle.inspect() +function TurtleController:TestForBlock(block_name, above, below) + above = above or false + below = below or false + if above and below then + error("Can only test for blocks in one direction!") + end + + local inspect_function = turtle.inspect + if above then + inspect_function = turtle.inspectUp + elseif below then + inspect_function = turtle.inspectDown + end + + local has_block, block_data = inspect_function() if not has_block then return false @@ -330,7 +357,11 @@ end ---@param slot number ---@param count number ---@return boolean -function TurtleController:SuckItem(slot, count) +function TurtleController:SuckItemFromChest(slot, count) + if not self:TestForBlock("minecraft:chest") then + error("Can't suck item: no chest!") + end + local previous_slot = turtle.getSelectedSlot() turtle.select(slot or 1) @@ -344,7 +375,11 @@ end ---@param slot number ---@param count number ---@return boolean -function TurtleController:DropItem(slot, count) +function TurtleController:DropItemIntoChest(slot, count) + if not self:TestForBlock("minecraft:chest") then + error("Can't drop item: no chest!") + end + local previous_slot = turtle.getSelectedSlot() turtle.select(slot or 1) @@ -355,7 +390,11 @@ function TurtleController:DropItem(slot, count) return dropped end -function TurtleController:DropInventory() +function TurtleController:DropInventoryIntoChest() + if not self:TestForBlock("minecraft:chest") then + error("Can't drop item: no chest!") + end + print("Dropping inventory into chest...") for slot = 1, 16 do @@ -379,7 +418,7 @@ function TurtleController:UnstockIfFull(skip_inventory_check) print("Turtle is unstocking...") self:MoveToPosition(0, 0, 0, self.config.storage_direction, true, true) - self:DropInventory() + self:DropInventoryIntoChest() self:RefuelIfEmpty() self:TurnToDirection(Direction.NORTH) @@ -401,7 +440,7 @@ function TurtleController:RefuelIfEmpty(skip_fuel_check) -- Clear our inventory into the storage chest self:MoveToPosition(0, 0, 0, self.config.storage_direction, true, true) - self:DropInventory() + self:DropInventoryIntoChest() -- Prepare refueling self:TurnToDirection(self.config.fuel_direction) @@ -420,7 +459,7 @@ function TurtleController:RefuelIfEmpty(skip_fuel_check) -- Refuel until we hit the refuel_amount local before_level = turtle.getFuelLevel() repeat - if not self:SuckItem(1, 1) then + if not self:SuckItemFromChest(1, 1) then error("Failed to suck fuel out of fuel chest!") end turtle.refuel() diff --git a/main.lua b/main.lua index 18a6d24..3bf5369 100644 --- a/main.lua +++ b/main.lua @@ -24,12 +24,13 @@ end controllers[choice]:Run() --- TODO: Test if there's a chest when dropping/sucking/mining (don't mine chests!) --- TODO: Add controller to build rooms with walls of a specified material --- TODO: Add configurable trash_list with items that won't be picked up -- TODO: When refueling but chest is missing, wait there until the user puts a chest with fuel --- TODO: Add emergency return routine if can't move (e.g. try to move in different directions first) +-- TODO: Improve error handling: Don't abort the program in all cases, +-- but wait until the user fixes the issue (e.g. places a chest) + -- TODO: Add shortcuts for the volume excavation: -- - Tunnel forward 3x2 or 3x3 with specified length -- - Excavate downwards (quarry) in a square, specify side length +-- TODO: Add controller to build rooms with walls of a specified material -- TODO: Add a stair building mode (specify side length, min 2x2) +-- TODO: Add configurable trash_list with items that won't be picked up