-- Global variable to store the name of the block to place
local requiredBlockName = nil
-- Helper function to perform a turtle action and check for success, pausing if needed
-- If the action fails, it will print an error, pause, and retry every second until it succeeds.
-- Returns true once the action successfully completes.
local function perform_action(action_func, error_message)
while not action_func() do
print("PAUSED: " .. error_message .. " Waiting for obstruction to clear...")
sleep(1) -- Wait for 1 second before retrying
end
print("Resumed: Obstruction cleared.")
return true
end
-- Function to find and select the required block type in the inventory.
-- It prioritizes the currently selected slot if it contains the required block.
-- Otherwise, it searches all other slots.
-- Returns true if the required block is found and selected, false otherwise.
local function findAndSelectRequiredBlock()
local currentSlot = turtle.getSelectedSlot()
local currentItem = turtle.getItemDetail(currentSlot)
-- Check if the current slot already has the required block and it's not empty
if currentItem and currentItem.name == requiredBlockName and currentItem.count > 0 then
return true
end
-- Search all slots for the required block
for i = 1, 16 do
local item = turtle.getItemDetail(i)
if item and item.name == requiredBlockName and item.count > 0 then
turtle.select(i)
print("Selected slot " .. i .. " containing '" .. requiredBlockName .. "'.")
return true
end
end
return false -- Required block not found in any slot
end
-- 1. place: Places a block under the turtle.
-- This function is robust:
-- - It first ensures the required block type is available and selected, pausing if not.
-- - Then, it attempts to place the block. If obstructed, it tries to clear the space
-- (attack for entities, dig for blocks) and retries placement, pausing if necessary.
-- Returns true once a block is successfully placed.
local function place()
-- Step 1: Ensure we have the required block selected.
-- This loop will pause the program until the required block is found in the inventory.
while not findAndSelectRequiredBlock() do
print("PAUSED: Out of required block type '" .. requiredBlockName .. "'. Waiting for more blocks...")
sleep(1) -- Wait for 1 second before re-checking inventory
end
print("Resumed: Required blocks found.")
-- Step 2: Attempt to place the block, clearing space if obstructed.
-- This loop will pause the program until the block can be placed.
while not turtle.placeDown() do
print("PAUSED: Failed to place block. Attempting to clear space below...")
-- Try attacking first (for entities)
if turtle.attackDown() then
print("Attacked entity below.")
else
-- If attacking failed or no entity, try digging (for blocks)
if turtle.digDown() then
print("Dug block below.")
else
print("Could not clear space below. Retrying...")
end
end
sleep(1) -- Wait for 1 second before retrying placement
end
print("Block placed successfully.")
return true
end
-- 2. line: Places a line of blocks of a given length.
-- The turtle will move forward relative to its current facing direction.
-- 'len': The length of the line.
-- Returns true on success (all blocks placed and movements completed).
local function line(len)
for l = 1, len do
if not place() then
-- This should theoretically not be reached due to the robust 'place' function,
-- but kept for logical completeness.
return false
end
if l < len then -- Don't move after placing the last block in the line
if not perform_action(turtle.forward, "Failed to move forward. Obstruction ahead.") then
-- This should theoretically not be reached due to the robust 'perform_action' function.
return false
end
end
end
return true
end
-- 3. platform: Builds a platform of specified length and width.
-- 'len': The length of the platform (along the turtle's initial forward direction).
-- 'wid': The width of the platform (perpendicular to the initial forward direction).
-- Returns true on success (platform fully built).
local function platform(len, wid)
-- This variable tracks if the current line is being built in the same direction
-- as the turtle's initial forward direction (e.g., +Z) or the opposite direction (e.g., -Z).
local current_line_direction_is_initial_forward = true
for w = 1, wid do
-- Build the current line. The 'line' function always moves turtle.forward().
-- The 'platform' function ensures the turtle is facing the correct direction before this call.
if not line(len) then
return false
end
if w < wid then -- If not the last row, prepare for the next row
if current_line_direction_is_initial_forward then
-- Finished a line moving in the initial forward direction.
-- Turtle is at the end of the line, facing that direction.
-- To move to the next row and then face opposite for the next line:
if not perform_action(turtle.turnRight, "Failed to turn right.") then return false end
if not perform_action(turtle.forward, "Failed to move forward to next row.") then return false end
if not perform_action(turtle.turnRight, "Failed to turn right.") then return false end
current_line_direction_is_initial_forward = false
else -- current_line_direction_is_initial_forward is false (finished line moving in opposite direction)
-- Finished a line moving in the opposite direction.
-- Turtle is at the end of the line, facing that direction.
-- To move to the next row and then face initial forward for the next line:
if not perform_action(turtle.turnLeft, "Failed to turn left.") then return false end
if not perform_action(turtle.forward, "Failed to move forward to next row.") then return false end
if not perform_action(turtle.turnLeft, "Failed to turn left.") then return false end
current_line_direction_is_initial_forward = true
end
end
end
return true
end
-- Main program logic
local args = { ... }
local length = tonumber(args[1])
local width = tonumber(args[2])
-- --- Initialization ---
-- Get the block type from the currently selected slot (usually slot 1 by default)
local initialSlot = turtle.getSelectedSlot()
local initialItem = turtle.getItemDetail(initialSlot)
if not initialItem then
print("Error: No item found in the currently selected slot (" .. initialSlot .. ").")
print("Please place the desired building block in this slot before running the program.")
return
end
requiredBlockName = initialItem.name
print("Building with block type: '" .. requiredBlockName .. "' (from slot " .. initialSlot .. ").")
-- Validate command-line arguments
if not length or not width or length < 1 or width < 1 then
print("Usage: buildplatform <length> <width>")
print(" <length>: The length of the platform (positive number)")
print(" <width>: The width of the platform (positive number)")
return
end
-- --- Start Construction ---
print("Starting platform construction for " .. length .. "x" .. width .. " platform...")
if platform(length, width) then
print("Platform built successfully!")
else
print("Platform construction failed.")
end
Comments