Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --------------------------------------------------------------------------------
- -- Mining Robot with Remote Commands and Configuration
- --
- -- On startup, the turtle (named "Minerobot <ID>") connects to rednet and waits
- -- for configuration from the handheld. The configuration sets the mine size
- -- (width and height) and the turtle’s starting facing direction.
- --
- -- After configuration, the turtle responds to these remote commands:
- -- "stats" - Sends its current coordinates.
- -- "start" - Begins mining with the configured parameters.
- -- "stop" - Stops mining after finishing the current layer.
- -- "home" - Returns to the starting position.
- -- "config:<width>:<height>:<facing>" - Updates configuration.
- --
- -- ASSUMPTIONS:
- -- - Starting position is (0,0,0).
- -- - A chest is behind the starting point.
- -- - Wireless modem attached on side "back" (adjust if needed).
- --------------------------------------------------------------------------------
- -- CONFIGURATION defaults (will be updated via remote command)
- local areaWidth = 16
- local areaHeight = 16
- local startFacing = 0 -- 0=East, 1=South, 2=West, 3=North
- local sleepTime = 0.1
- -- Position and orientation tracking (starting at (0,0,0))
- local posX, posY, posZ = 0, 0, 0
- local facing = startFacing -- will be updated with config
- local startX, startY, startZ = 0, 0, 0
- -- Control flags
- local miningActive = false
- local stopMining = false
- -- Modem configuration
- local modemSide = "left"
- if not rednet.isOpen(modemSide) then
- rednet.open(modemSide)
- end
- local robotName = "Minerobot " .. os.getComputerID()
- rednet.broadcast("checkin:" .. robotName, "control")
- print("Checked in as " .. robotName)
- print("Waiting for configuration...")
- --------------------------------------------------------------------------------
- -- INVENTORY & FUEL FUNCTIONS
- --------------------------------------------------------------------------------
- local function inventoryFull()
- for slot = 1, 14 do
- if turtle.getItemCount(slot) == 0 then
- return false
- end
- end
- return true
- end
- local function dumpInventory()
- for slot = 1, 14 do
- turtle.select(slot)
- turtle.drop()
- end
- turtle.select(1)
- end
- local function ensureFuel()
- if turtle.getFuelLevel() == "unlimited" then return end
- local threshold = 10
- if turtle.getFuelLevel() < threshold then
- print("Low fuel (" .. turtle.getFuelLevel() .. "). Refueling...")
- for slot = 1, 16 do
- turtle.select(slot)
- turtle.refuel(1)
- if turtle.getFuelLevel() >= threshold then break end
- end
- if turtle.getFuelLevel() < threshold then
- error("Not enough fuel. Please add more fuel and restart.")
- end
- end
- end
- --------------------------------------------------------------------------------
- -- TURNING & FACING FUNCTIONS
- --------------------------------------------------------------------------------
- local function turnLeft()
- turtle.turnLeft()
- facing = (facing + 3) % 4
- end
- local function turnRight()
- turtle.turnRight()
- facing = (facing + 1) % 4
- end
- local function turnAround()
- turtle.turnLeft()
- turtle.turnLeft()
- facing = (facing + 2) % 4
- end
- local function faceDirection(dir)
- local diff = (dir - facing) % 4
- if diff == 1 then
- turnRight()
- elseif diff == 2 then
- turnAround()
- elseif diff == 3 then
- turnLeft()
- end
- end
- --------------------------------------------------------------------------------
- -- MOVEMENT FUNCTIONS
- --------------------------------------------------------------------------------
- local function mineForwardStep()
- if inventoryFull() then
- return false
- end
- ensureFuel()
- turtle.dig()
- while not turtle.forward() do
- if turtle.detect() then turtle.dig() end
- sleep(sleepTime)
- end
- if facing == 0 then
- posX = posX + 1
- elseif facing == 1 then
- posZ = posZ + 1
- elseif facing == 2 then
- posX = posX - 1
- elseif facing == 3 then
- posZ = posZ - 1
- end
- turtle.digUp()
- turtle.digDown()
- return true
- end
- local function moveForwardNoDump()
- ensureFuel()
- turtle.dig()
- while not turtle.forward() do
- if turtle.detect() then turtle.dig() end
- sleep(sleepTime)
- end
- if facing == 0 then
- posX = posX + 1
- elseif facing == 1 then
- posZ = posZ + 1
- elseif facing == 2 then
- posX = posX - 1
- elseif facing == 3 then
- posZ = posZ - 1
- end
- end
- local function moveUpNoDump()
- ensureFuel()
- turtle.digUp()
- while not turtle.up() do
- turtle.digUp()
- sleep(sleepTime)
- end
- posY = posY + 1
- end
- local function moveDownNoDump()
- ensureFuel()
- turtle.digDown()
- while not turtle.down() do
- turtle.digDown()
- sleep(sleepTime)
- end
- posY = posY - 1
- end
- --------------------------------------------------------------------------------
- -- 3D NAVIGATION FUNCTION
- --------------------------------------------------------------------------------
- local function navigateTo3DNoDump(tx, ty, tz)
- while posY < ty do
- moveUpNoDump()
- end
- while posY > ty do
- moveDownNoDump()
- end
- if posX < tx then
- faceDirection(0)
- while posX < tx do
- moveForwardNoDump()
- end
- elseif posX > tx then
- faceDirection(2)
- while posX > tx do
- moveForwardNoDump()
- end
- end
- if posZ < tz then
- faceDirection(1)
- while posZ < tz do
- moveForwardNoDump()
- end
- elseif posZ > tz then
- faceDirection(3)
- while posZ > tz do
- moveForwardNoDump()
- end
- end
- end
- --------------------------------------------------------------------------------
- -- DUMP INVENTORY ROUTINE
- --------------------------------------------------------------------------------
- local function manageInventoryDump()
- local savedX, savedY, savedZ = posX, posY, posZ
- local savedFacing = facing
- print("Inventory full. Going to dump...")
- navigateTo3DNoDump(startX, startY, startZ)
- faceDirection(2) -- face the chest
- dumpInventory()
- faceDirection(0)
- print("Dump complete. Returning to mining spot...")
- navigateTo3DNoDump(savedX, savedY, savedZ)
- faceDirection(savedFacing)
- end
- --------------------------------------------------------------------------------
- -- DESCEND TO NEXT LAYER FUNCTION
- --------------------------------------------------------------------------------
- local function descendToNextLayer()
- navigateTo3DNoDump(startX, posY, startZ)
- for i = 1, 3 do
- turtle.digDown()
- while not turtle.down() do
- turtle.digDown()
- sleep(sleepTime)
- end
- posY = posY - 1
- end
- return true
- end
- --------------------------------------------------------------------------------
- -- MINE ONE LAYER (Serpentine based on configured areaWidth and areaHeight)
- --------------------------------------------------------------------------------
- local function mineLayer()
- for row = 0, areaHeight - 1 do
- if row % 2 == 0 then
- faceDirection( (startFacing + 0) % 4 ) -- use starting direction for even rows
- for i = 1, areaWidth - 1 do
- if not mineForwardStep() then
- manageInventoryDump()
- mineForwardStep()
- end
- end
- else
- faceDirection( (startFacing + 2) % 4 ) -- opposite direction for odd rows
- for i = 1, areaWidth - 1 do
- if not mineForwardStep() then
- manageInventoryDump()
- mineForwardStep()
- end
- end
- end
- if row < areaHeight - 1 then
- faceDirection( (startFacing + 1) % 4 ) -- move to next row (assumes southward shift)
- if not mineForwardStep() then
- manageInventoryDump()
- mineForwardStep()
- end
- end
- end
- navigateTo3DNoDump(0, posY, 0)
- faceDirection(startFacing)
- end
- --------------------------------------------------------------------------------
- -- MINING LOOP
- --------------------------------------------------------------------------------
- local function miningLoop()
- print("Mining started.")
- while miningActive and not stopMining do
- mineLayer()
- local success, data = turtle.inspectDown()
- if success and data.name == "minecraft:bedrock" then
- print("Bedrock below. Stopping mining.")
- miningActive = false
- break
- end
- print("Layer complete. Descending...")
- if not descendToNextLayer() then
- print("Cannot descend further. Stopping mining.")
- miningActive = false
- break
- end
- sleep(0.1) -- yield frequently
- end
- print("Mining stopped.")
- end
- --------------------------------------------------------------------------------
- -- RETURN HOME FUNCTION
- --------------------------------------------------------------------------------
- local function returnHome()
- print("Returning home...")
- navigateTo3DNoDump(startX, startY, startZ)
- faceDirection(startFacing)
- print("Home reached.")
- end
- --------------------------------------------------------------------------------
- -- REMOTE COMMAND LISTENER (Improved Responsiveness)
- --------------------------------------------------------------------------------
- local function remoteListener()
- while true do
- local sender, message, protocol = rednet.receive(nil, 0.5)
- if message then
- if message == "stats" then
- local statusMsg = "Position: (" .. posX .. ", " .. posY .. ", " .. posZ .. ")"
- rednet.send(sender, statusMsg)
- print("Sent stats to " .. sender)
- elseif message == "start" then
- if not miningActive then
- miningActive = true
- stopMining = false
- print("Received START command.")
- parallel.spawn(miningLoop)
- end
- elseif message == "stop" then
- if miningActive then
- stopMining = true
- miningActive = false
- print("Received STOP command.")
- end
- elseif message == "home" then
- stopMining = true
- miningActive = false
- print("Received HOME command.")
- returnHome()
- elseif message:sub(1,7) == "config:" then
- local width, height, face = message:match("config:(%d+):(%d+):(%d+)")
- if width and height and face then
- areaWidth = tonumber(width)
- areaHeight = tonumber(height)
- startFacing = tonumber(face)
- facing = startFacing
- print("Configured: mine size " .. areaWidth .. "x" .. areaHeight ..
- " and starting facing " .. startFacing)
- rednet.send(sender, "configured")
- else
- rednet.send(sender, "config error")
- end
- end
- end
- sleep(0.1)
- end
- end
- --------------------------------------------------------------------------------
- -- MAIN: Run remoteListener in parallel (ensuring responsiveness)
- --------------------------------------------------------------------------------
- parallel.waitForAny(remoteListener, function() while true do sleep(0.1) end end)
- if rednet.isOpen(modemSide) then
- rednet.close(modemSide)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement