1

Implement testing for blocks in front/above/below the turtle so we don't mine chests

This commit is contained in:
2025-10-07 17:13:34 +02:00
parent a1d4d65c42
commit 1be0d4ce33
3 changed files with 53 additions and 13 deletions

View File

@ -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

View File

@ -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()

View File

@ -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