Skip to content

Instantly share code, notes, and snippets.

@berkus
Last active August 29, 2015 14:22
Show Gist options
  • Save berkus/22efa1cf3c0913ecc3af to your computer and use it in GitHub Desktop.
Save berkus/22efa1cf3c0913ecc3af to your computer and use it in GitHub Desktop.
Minecraft turtle machinery
-- To load to turtle: pastebin get aKard6z3 dig
-- Simple digger --
-- When called, will dig down to bedrock, move one forward and dig back up to original location.
-- Call "dig <N>" - N times dig down and back up.
-- Can refuel from any slot.
-- Will group resources into same slot.
-- Will drop junk items if no free space.
--
-- Refueling
--
-- refuel turtle or pause it until more fuel is available
function refuel()
if turtle.getFuelLevel() == 0 then
local first = true
local s = turtle.getSelectedSlot()
while true do
for slot=1,16 do
turtle.select(slot)
if turtle.refuel(0) then
turtle.refuel(1)
print("More fuel loaded, fuel level "..turtle.getFuelLevel())
turtle.select(s)
return
end
end -- for
if first then
print("No fuel, load me up!")
first = false
end
sleep(1)
end -- while
end
end
--
-- Movement
--
-- move in any direction making sure we have fuel to go
function move(f)
refuel()
return f()
end
-- how many steps up to return to base
local returnSteps = 0
function stepDown()
if move(turtle.down) then
returnSteps = returnSteps + 1
return true
end
return false
end
function stepUp()
if move(turtle.up) then
returnSteps = returnSteps - 1
return true
end
return false
end
--
-- Stash cleanup
--
function isJunk(item)
if item.name == "minecraft:dirt"
or item.name == "minecraft:gravel"
or item.name == "minecraft:sand"
or item.name == "minecraft:cobblestone"
or item.name == "chisel:limestone"
or item.name == "chisel:marble"
or item.name == "chisel:granite"
or item.name == "chisel:diorite"
then
return true
end
return false
end
-- return slot index that can be dropped or 0 if none
function findJunkItemSlot()
for slot=1,16 do
if turtle.getItemCount(slot) > 0 then
item = turtle.getItemDetail(slot)
if isJunk(item) then
return slot
end
end
end
return 0
end
-- Determine if robot can take any more items of same type
function canStashFit(item)
for slot=1,16 do
if turtle.getItemCount(slot) == 0 then
return true
end
inSlot = turtle.getItemDetail(slot)
if inSlot.name == item.name
and inSlot.count < 64
then
return true
end
end
return false
end
-- inspect item and see if we can take it
function willFitItem(inspect)
local ok, item = inspect()
if not ok then return true end
return canStashFit(item)
end
-- tidy up items in stash
function repackageStash()
local s = turtle.getSelectedSlot()
for slot=1,15 do
if turtle.getItemCount(slot) > 0 then
turtle.select(slot)
for sl2=slot+1,16 do
if turtle.compareTo(sl2) then
turtle.select(sl2)
turtle.transferTo(slot)
turtle.select(slot)
end
end
end
end
turtle.select(s)
end
-- Get rid of the bad items
-- if there's no more space
function getRidOfJunk()
local s = turtle.getSelectedSlot()
while true do
slot = findJunkItemSlot()
if slot == 0 then
turtle.select(s)
return
end
turtle.select(slot)
turtle.drop()
end
end
--
-- Mining operations
--
-- dig up until we can move in there
function digUp()
while turtle.detectUp() and not isBedrock(turtle.inspectUp) do
if not willFitItem(turtle.inspectUp) then
getRidOfJunk()
end
turtle.digUp()
sleep(.1) -- let falling stuff fall
end
end
-- dig down until we can move in there
function digDown()
while turtle.detectDown() and not isBedrock(turtle.inspectDown) do
if not willFitItem(turtle.inspectDown) then
getRidOfJunk()
end
turtle.digDown()
-- we ARE the falling stuff, no need to wait
end
end
-- dig forward until we can move in there
function digForward()
while turtle.detect() and not isBedrock(turtle.inspect) do
if not willFitItem(turtle.inspect) then
getRidOfJunk()
end
turtle.dig()
sleep(.1) -- let falling stuff fall
end
end
-- e.g. isBedrock(turtle.inspectDown)
function isBedrock(inspect)
local found, data = inspect()
if not found then return false end
return data.name == "minecraft:bedrock"
end
-- if we're stuck under the bedrock, try to squeeze back out
--
-- it should never happen that we're stuck with bedrock above AND behind the turtle
-- becase this is essentially where we came from, and we checked conditions on entry.
function recoverFromUnderTheBed()
if not move(turtle.back) then
print("I'm stuck!") -- but SHIT HAPPENS!
-- todo: send wifi signal
end
digUp()
stepUp()
-- skip bedrock in front before digging into it
while isBedrock(turtle.inspect) do
digUp()
stepUp()
end
digForward()
return move(turtle.forward)
end
-- go down all the way to bedrock, then one forward and back all the way up
function toTheCenterOfTheEarthAndBack()
-- 1ST COLUMN dig down
-- dig down until we hit bedrock
while not isBedrock(turtle.inspectDown) do
digDown()
stepDown()
end
-- as long as there's bedrock forward - go up
while returnSteps > 0 and isBedrock(turtle.inspect) do
digUp()
if returnSteps > 0 then
stepUp()
end
end
-- go one forward
digForward()
if not move(turtle.forward) then
print("Failed to move forward, just returning up")
end
-- 2ND COLUMN dig up
-- dig down until we hit bedrock
while not isBedrock(turtle.inspectDown) do
digDown()
stepDown()
end
-- dig up until we end up at start
while returnSteps > 0 do
digUp()
if not stepUp() and isBedrock(turtle.inspectUp) then
-- while digging up we may end up _under_ bedrock and then we need to back out
recoverFromUnderTheBed()
end
end
-- 3RD COLUMN - prepare for new dig down
digForward()
move(turtle.forward)
repackageStash()
-- assert we're at level 0
return returnSteps == 0
end
--
-- main
--
local TotalSteps = 1
local args = { ... }
if #args > 0 then
TotalSteps = tonumber(args[1])
end
if TotalSteps < 1 or TotalSteps > 100 then
print("too many steps, enter 1..100")
os.exit()
end
for step=1,TotalSteps do
if not toTheCenterOfTheEarthAndBack() then
print("Lost sync")
os.exit()
end
end
local function move(F)
while not F() do
sleep(1)
end
end
local function refuel()
if turtle.getFuelLevel() < 10 then
turtle.select(1)
turtle.refuel(1)
end
end
local function reseed()
local seedCount, refillCount = turtle.getItemCount(2), 0
refillCount = 64 - seedCount
if (seedCount == 0) then
print("Out of seeds: place seeds in slot 2 to continue")
repeat
sleep(1)
until (turtle.getItemCount(2) > 0)
elseif (seedCount < 16) then
turtle.select(2)
for n = 3, 16, 1 do
if (turtle.compareTo(n) == true) then
turtle.select(n)
if (refillCount > turtle.getItemCount(n)) then
turtle.transferTo(2, turtle.getItemCount(n))
refillCount = 64 - turtle.getItemCount(1)
else
turtle.transferTo(2, refillCount)
break
end
turtle.select(1)
end
end
end
end
local function step(n)
for i = 1,n,1 do
refuel()
move(turtle.forward)
turtle.digDown()
reseed()
turtle.select(2)
turtle.placeDown()
end
end
local function two_rows()
step(32)
move(turtle.forward)
turtle.turnRight()
move(turtle.forward)
turtle.turnRight()
step(32)
move(turtle.forward)
end
local function unload()
for n= 3,16,1 do
turtle.select(n)
if (turtle.getItemCount() > 0) then
repeat
sleep(1)
print ("Dropping slot ", n)
until (turtle.dropDown())
end
end
end
two_rows()
turtle.turnLeft()
move(turtle.forward)
turtle.turnLeft()
two_rows()
turtle.turnLeft()
move(turtle.forward)
move(turtle.forward)
turtle.turnLeft()
two_rows()
turtle.turnLeft()
move(turtle.forward)
turtle.turnLeft()
two_rows()
turtle.turnRight()
move(turtle.forward)
move(turtle.forward)
move(turtle.forward)
move(turtle.forward)
move(turtle.forward)
move(turtle.forward)
move(turtle.forward)
move(turtle.forward)
turtle.turnRight()
unload()
-- build NxN cobble floor with 4 walls
function selectCobbleSlot()
for slot=1,16 do
inSlot = turtle.getItemDetail(slot)
if inSlot and inSlot.name == "minecraft:cobblestone" then
turtle.select(slot)
return true
end
end
return false
end
function move(f)
if turtle.getFuelLevel() == 0 then
for slot=1,16 do
turtle.select(slot)
if turtle.refuel(0) then
turtle.refuel(1)
break
end
end
if turtle.getFuelLevel() == 0 then
print("No fuel, stopping")
return false
end
end
dig()
return f()
end
function dig()
while turtle.detect() do
turtle.dig()
end
while turtle.detectUp() do
turtle.digUp()
end
end
function placeOne()
if turtle.detectDown() then
turtle.digDown()
end
if not selectCobbleSlot() then
return false
end
return turtle.placeDown()
end
function placeRow(steps)
for x=1,steps-1 do
placeOne()
move(turtle.forward)
end
placeOne()
end
-- N must be divisible by 2
function placeFloorTile(N)
for r=1,N/2 do
placeRow(N)
turtle.turnRight()
move(turtle.forward)
turtle.turnRight()
placeRow(N)
turtle.turnLeft()
move(turtle.forward)
turtle.turnLeft()
end
end
function placeWall(N)
placeRow(N)
turtle.turnRight()
placeRow(N)
turtle.turnRight()
placeRow(N)
turtle.turnRight()
placeRow(N)
end
--
-- main
--
local N = 8
local args = { ... }
if #args > 0 then
N = tonumber(args[1])
end
if N > 10 then
print("Room too big, 10x10 max")
os.exit()
end
placeFloorTile(N)
turtle.turnLeft()
move(turtle.forward)
for x=1,4 do
move(turtle.up)
placeWall(N)
turtle.turnRight()
end
for x=1,N/2 do
move(turtle.forward)
end
for x=1,4 do
turtle.digDown()
turtle.down()
end
-- Get script from this gist into your miner
http.request("https://gist.githubusercontent.com/berkus/22efa1cf3c0913ecc3af/raw/6bd0fa6e656b88328c8652a03a72a2e305e18caa/mine")
local requesting = true
while requesting do
local event, url, sourceText = os.pullEvent()
if event == "http_success" then
local respondedText = sourceText.readAll()
sourceText.close()
h = fs.open("mine", "w")
h.write(respondedText)
h.close()
requesting = false
elseif event == "http_failure" then
print("Server didn't respond.")
requesting = false
end
end
-- Get script from this gist into your miner
-- Simple three-liner version, but no error checking
url = "https://gist.githubusercontent.com/berkus/22efa1cf3c0913ecc3af/raw/5acfb17d864b01ada21adbe661d483da374b9574/mine"
h = fs.open("mine", "w")
h.write(http.get(url).readAll())
h.close()
-- Simple miner
-- Call it "mine <steps> [none|left|right]"
-- If you place an item in slot 3 before starting mining,
-- bot will drop all items of the same type on the floor
-- before returning back after mining.
-- Place torches in this slot
local TorchSlot = 2
-- Place item you want robot to never carry in this slot
local BadItemSlot = 3
local BadItem = nil
function move(f)
if turtle.getFuelLevel() == 0 then
for slot=1,16 do
turtle.select(slot)
if turtle.refuel(0) then
turtle.refuel(1)
break
end
end
if turtle.getFuelLevel() == 0 then
print("No fuel, stopping")
return false
end
end
return f()
end
-- Can place torches once every 5 steps
-- on the left or the right wall
-- "left", "right" or default "none"
local PlaceTorchOn = "none"
function placeTorch(step, side)
if PlaceTorchOn == "none" then return end
if PlaceTorchOn == side then
if step % 5 == 0 then
turtle.select(TorchSlot)
turtle.place()
end
end
end
function isBadItemSlotArmed()
turtle.select(BadItemSlot)
if turtle.getItemCount() > 0 then
BadItem = turtle.getItemDetail()
return true
end
return false
end
-- Determine if robot can take any more items of same type
function isStashFullOf(item)
for slot=1,16 do
inSlot = turtle.getItemDetail(slot)
if inSlot.name == item.name and inSlot.count < 64 then
return false
end
if turtle.getItemCount(slot) == 0 then
return false
end
end
return true
end
-- Get rid of the bad item if there's no more place for it
function emptyStash()
if not BadItem then return end
for slot=1,16 do
inSlot = turtle.getItemDetail(slot)
if inSlot and inSlot.name == BadItem.name then
turtle.select(slot)
turtle.drop()
end
end
end
function digOne()
while turtle.detect() do
turtle.dig()
end
emptyStash()
end
function digStep(step)
turtle.digUp()
turtle.turnLeft()
digOne()
placeTorch(step, "left")
turtle.turnRight()
turtle.turnRight()
digOne()
placeTorch(step, "right")
move(turtle.up)
digOne()
turtle.turnLeft()
turtle.turnLeft()
digOne()
turtle.turnRight()
move(turtle.down)
digOne()
return move(turtle.forward)
end
local TotalSteps = 1
local args = { ... }
if #args > 0 then
TotalSteps = tonumber(args[1])
end
if #args > 1 then
PlaceTorchOn = args[2]
end
-- Validation
if TotalSteps > 300 then
print("too many steps, go below 300")
os.exit()
end
if isBadItemSlotArmed() then
print("will drop "..BadItem.name.." on the floor")
end
for step=1,TotalSteps do
print("step "..step.." of "..TotalSteps)
if not digStep(step) then
break
end
end
emptyStash()
print("returning to base")
for step=1,TotalSteps do
move(turtle.back)
end
fnUP = {
move = turtle.up,
dig = turtle.digUp,
attack = turtle.attackUp
}
fnDOWN = {
move = turtle.down,
dig = turtle.digDown,
attack = turtle.attackDown
}
fnFORWARD = {
move = turtle.forward,
dig = turtle.dig,
attack = turtle.attack
}
-- return true if item count in slot 2 == 64
local function refill2()
local cobbleCount = turtle.getItemCount(2)
local refillCount = 64 - cobbleCount
if (cobbleCount == 0) then
print("Out of tunnel buildblock: place buildblock in slot 2 to continue")
repeat
sleep(1)
until (turtle.getItemCount(2) > 0)
else
for n = 3,16 do
turtle.select(2)
if (turtle.compareTo(n) == true) then
turtle.select(n)
if (refillCount > turtle.getItemCount(n)) then
turtle.transferTo(2, turtle.getItemCount(n))
refillCount = 64 - turtle.getItemCount(2)
else
turtle.transferTo(2, refillCount)
break
end
end
end
end
return turtle.getItemCount(2) == 64
end
local function digUp()
while turtle.detectUp() do
turtle.digUp()
end
end
local function placeUp()
if not turtle.detectUp() then
refill2()
turtle.select(2)
turtle.placeUp()
return true
end
return false
end
local function move(fn)
if turtle.getFuelLevel() == 0 then
for slot=1,16 do
turtle.select(slot)
if turtle.refuel(0) then
turtle.refuel(1)
break
end
end
if turtle.getFuelLevel() == 0 then
print("No fuel, stopping...")
return false
end
end
-- mooooooveeee soooooo4aaaaraaa
while not fn.move() do
-- gravel dropped on turtle from above
if not turtle.detect() then
digUp()
placeUp()
else
fn.dig()
end
fn.attack()
sleep(1)
end
end
local function place()
if not turtle.detect() then
refill2()
turtle.select(2)
turtle.place()
return true
end
return false
end
local function placeDown()
if not turtle.detectDown() then
refill2()
turtle.select(2)
turtle.placeDown()
return true
end
return false
end
function emptyStash()
local busySlots = 0
-- check fullness
for slot=3,16 do
inSlot = turtle.getItemDetail(slot)
if inSlot then
busySlots = busySlots + 1
end
end
-- empty if no more empty slots
if busySlots > 12 then
for slot=3,16 do
inSlot = turtle.getItemDetail(slot)
if inSlot then
if (inSlot.name == "minecraft:cobblestone")
or (inSlot.name == "minecraft:dirt")
or (inSlot.name == "chisel:granite")
or (inSlot.name == "chisel:limestone")
or (inSlot.name == "chisel:marble")
or (inSlot.name == "minecraft:gravel")
or (inSlot.name == "chisel:diorite")
-- or (inSlot.name == "minecraft:dirt")
then
turtle.select(slot)
turtle.drop()
end
end
end
end
end
local function dig()
while turtle.detect() do
turtle.dig()
end
end
-- 1 floor step
local function step1()
dig()
move(fnFORWARD)
placeDown()
end
-- 2 floor step
local function step2()
dig()
move(fnFORWARD)
placeUp()
end
local function placeTorch()
turtle.select(1)
if turtle.getItemCount() < 1 then
print("No torches in slot 1, place torches in slot 1")
return false
end
turtle.turnRight()
turtle.place()
turtle.turnLeft()
return true
end
-- MAIN
local args = { ... }
local length = 0
local width = 3
local depth = 0
local needEmptyStash = true
local needReturn = true
if #args < 1 then
print( "Usage: tunnel <length> [width, default 3] [any = do not return to start]" )
return
else
length = tonumber( args[1] )
if length < 1 then
print( "Tunnel length must be > 0" )
return
end
end
if #args > 1 then
width = tonumber( args[2] )
if width < 1 then
print( "Tunnel width must be > 0" )
return
end
end
if #args > 2 then
needReturn = false
end
print( "Tunnelling: length="..length.." width="..width.." height=2" )
for i=1,length do
step1(false)
turtle.turnRight()
for j=2,width do
step1()
if (i % 7 == 0) and (j % 7 == 0) then
placeTorch()
end
end
place()
digUp()
move(fnUP)
place()
placeUp()
turtle.turnRight()
turtle.turnRight()
for j=2,width do
step2()
end
place()
move(fnDOWN)
place()
turtle.turnRight()
if (i == 2) or (i % 7 == 0) then
placeTorch()
end
depth = depth + 1
if needEmptyStash and (i % 3 == 0) and refill2() then
emptyStash()
end
end
if needReturn then
print( "Returning to start..." )
-- Return to where we started
turtle.turnLeft()
turtle.turnLeft()
while depth > 0 do
move(fnFORWARD)
depth = depth - 1
end
turtle.turnRight()
turtle.turnRight()
end
print( "Tunnel complete." )
--
-- Usage: mt2 length [width=3] [needEpmtyStash=true]
--
local function move(f)
if turtle.getFuelLevel() == 0 then
for slot=1,16 do
turtle.select(slot)
if turtle.refuel(0) then
turtle.refuel(1)
break
end
end
if turtle.getFuelLevel() == 0 then
print("No fuel, stopping...")
return false
end
end
-- mooooooveeee soooooo4aaaaraaa
while not f() do
turtle.dig()
turtle.attack()
sleep(1)
end
end
-- return true if item count in slot 2 == 64
local function refill2()
local cobbleCount = turtle.getItemCount(2)
local refillCount = 64 - cobbleCount
if (cobbleCount == 0) then
print("Out of tunnel buildblock: place buildblock in slot 2 to continue")
repeat
sleep(1)
until (turtle.getItemCount(2) > 0)
else
for n = 3,16 do
turtle.select(2)
if (turtle.compareTo(n) == true) then
turtle.select(n)
if (refillCount > turtle.getItemCount(n)) then
turtle.transferTo(2, turtle.getItemCount(n))
refillCount = 64 - turtle.getItemCount(2)
else
turtle.transferTo(2, refillCount)
break
end
end
end
end
return turtle.getItemCount(2) == 64
end
local function place()
if not turtle.detect() then
refill2()
turtle.select(2)
turtle.place()
return true
end
return false
end
local function placeUp()
if not turtle.detectUp() then
refill2()
turtle.select(2)
turtle.placeUp()
return true
end
return false
end
local function placeDown()
if not turtle.detectDown() then
refill2()
turtle.select(2)
turtle.placeDown()
return true
end
return false
end
function emptyStash()
for slot=3,16 do
inSlot = turtle.getItemDetail(slot)
if inSlot then
if (inSlot.name == "minecraft:cobblestone") or (inSlot.name == "minecraft:dirt") then
turtle.select(slot)
turtle.drop()
end
end
end
end
local function dig()
while turtle.detect() do
turtle.dig()
end
end
local function digUp()
while turtle.detectUp() do
turtle.digUp()
end
end
-- 1 floor step
local function step1()
dig()
move(turtle.forward)
placeDown()
end
-- 2 floor step
local function step2()
dig()
move(turtle.forward)
placeUp()
end
local function placeTorch()
turtle.select(1)
if turtle.getItemCount() < 1 then
print("No torches in slot 1, place torches in slot 1")
return false
end
turtle.turnRight()
turtle.place()
turtle.turnLeft()
return true
end
-- MAIN
local args = { ... }
local length = 0
local width = 3
local depth = 0
local needEmptyStash = true
if #args < 1 then
print( "Usage: tunnel <length> [width, default 3] [no emptyStash, default false]" )
return
else
length = tonumber( args[1] )
if length < 1 then
print( "Tunnel length must be > 0" )
return
end
end
if #args > 1 then
width = tonumber( args[2] )
if width < 1 then
print( "Tunnel width must be > 0" )
return
end
end
if #args > 2 then
needEmptyStash = false
end
print( "Tunnelling: length="..length.." width="..width.." height=2" )
for i=1,length do
step1(false)
turtle.turnRight()
for j=2,width do
step1()
if (i % 7 == 0) and (j % 7 == 0) then
placeTorch()
end
end
place()
digUp()
move(turtle.up)
place()
placeUp()
turtle.turnRight()
turtle.turnRight()
for j=2,width do
step2()
end
place()
move(turtle.down)
place()
turtle.turnRight()
if (i == 2) or (i % 7 == 0) then
placeTorch()
end
depth = depth + 1
if needEmptyStash and (i % 3 == 0) and refill2() then
emptyStash()
end
end
print( "Returning to start..." )
-- Return to where we started
turtle.turnLeft()
turtle.turnLeft()
while depth > 0 do
move(turtle.forward)
depth = depth - 1
end
turtle.turnRight()
turtle.turnRight()
print( "Tunnel complete." )
local tArgs = { ... }
if #tArgs ~= 1 then
print( "Usage: tunnel <length>" )
return
end
-- Mine in a quarry pattern until we hit something we can't dig
local length = tonumber( tArgs[1] )
if length < 1 then
print( "Tunnel length must be positive" )
return
end
local depth = 0
local collected = 0
local function collect()
collected = collected + 1
if math.fmod(collected, 25) == 0 then
print( "Mined "..collected.." items." )
end
end
local function tryDig()
while turtle.detect() do
if turtle.dig() then
collect()
sleep(0.5)
else
return false
end
end
return true
end
local function tryDigUp()
while turtle.detectUp() do
if turtle.digUp() then
collect()
sleep(0.5)
else
return false
end
end
return true
end
local function tryDigDown()
while turtle.detectDown() do
if turtle.digDown() then
collect()
sleep(0.5)
else
return false
end
end
return true
end
local function refuel()
local fuelLevel = turtle.getFuelLevel()
if fuelLevel == "unlimited" or fuelLevel > 0 then
return
end
local function tryRefuel()
for n=1,16 do
if turtle.getItemCount(n) > 0 then
turtle.select(n)
if turtle.refuel(1) then
turtle.select(1)
return true
end
end
end
turtle.select(1)
return false
end
if not tryRefuel() then
print( "Add more fuel to continue." )
while not tryRefuel() do
os.pullEvent( "turtle_inventory" )
end
print( "Resuming Tunnel." )
end
end
local function tryUp()
refuel()
while not turtle.up() do
if turtle.detectUp() then
if not tryDigUp() then
return false
end
elseif turtle.attackUp() then
collect()
else
sleep( 0.5 )
end
end
return true
end
local function tryDown()
refuel()
while not turtle.down() do
if turtle.detectDown() then
if not tryDigDown() then
return false
end
elseif turtle.attackDown() then
collect()
else
sleep( 0.5 )
end
end
return true
end
local function tryForward()
refuel()
while not turtle.forward() do
if turtle.detect() then
if not tryDig() then
return false
end
elseif turtle.attack() then
collect()
else
sleep( 0.5 )
end
end
return true
end
print( "Tunnelling..." )
for n=1,length do
turtle.placeDown()
tryDigUp()
turtle.turnLeft()
tryDig()
tryUp()
tryDig()
turtle.turnRight()
turtle.turnRight()
tryDig()
tryDown()
tryDig()
turtle.turnLeft()
if n<length then
tryDig()
if not tryForward() then
print( "Aborting Tunnel." )
break
end
else
print( "Tunnel complete." )
end
end
--[[
print( "Returning to start..." )
-- Return to where we started
turtle.turnLeft()
turtle.turnLeft()
while depth > 0 do
if turtle.forward() then
depth = depth - 1
else
turtle.dig()
end
end
turtle.turnRight()
turtle.turnRight()
]]
print( "Tunnel complete." )
print( "Mined "..collected.." items total." )
-- build cobble road of width 2 and X steps ahead
function selectCobbleSlot()
for slot=1,16 do
inSlot = turtle.getItemDetail(slot)
if inSlot and inSlot.name == "minecraft:cobblestone" then
turtle.select(slot)
return true
end
end
return false
end
function move(f)
if turtle.getFuelLevel() == 0 then
for slot=1,16 do
turtle.select(slot)
if turtle.refuel(0) then
turtle.refuel(1)
break
end
end
if turtle.getFuelLevel() == 0 then
print("No fuel, stopping")
return false
end
end
dig()
return f()
end
function dig()
while turtle.detect() do
turtle.dig()
end
while turtle.detectUp() do
turtle.digUp()
end
end
function placeOne()
if turtle.detectDown() then
turtle.digDown()
end
if not selectCobbleSlot() then
return false
end
return turtle.placeDown()
end
function placeTwoStep()
move(turtle.forward)
placeOne()
turtle.turnRight()
move(turtle.forward)
turtle.turnLeft()
placeOne()
move(turtle.forward)
placeOne()
turtle.turnLeft()
move(turtle.forward)
turtle.turnRight()
return placeOne()
end
local TotalSteps = 2
local args = { ... }
if #args > 0 then
TotalSteps = tonumber(args[1])
end
-- Validation
if TotalSteps > 300 then
print("too many steps, go below 300")
os.exit()
end
TotalSteps = TotalSteps / 2
for step=1,TotalSteps do
print("twostep "..step.." of "..TotalSteps)
if not placeTwoStep() then
break
end
end
print("returning to base")
TotalSteps = TotalSteps * 2
for step=1,TotalSteps do
move(turtle.back)
end
-- To load to turtle: pastebin get vf2vv3k9 room
-- Build a room with floor, walls, windows and roof.
-- Slot 1 is for floor material
-- Slot 2 is for wall material
-- Slot 3 is for roof material
-- Slot 4 is for window material
-- Similar materials from other slots will be used.
local RoomWidth = 16
local RoomDepth = 16
local WallHeight = 4
local NumFloors = 1
local floorBlock = turtle.getItemDetail(1)
local wallBlock = turtle.getItemDetail(2) or floorBlock
local roofBlock = turtle.getItemDetail(3) or floorBlock
local windowBlock = turtle.getItemDetail(4) or floorBlock
-- how many steps up to return to base level
local returnSteps = 0
--
-- Refueling
--
-- refuel turtle or pause it until more fuel is available
function refuel()
if turtle.getFuelLevel() == 0 then
local first = true
local s = turtle.getSelectedSlot()
while true do
for slot=1,16 do
turtle.select(slot)
if turtle.refuel(0) then
turtle.refuel(1)
print("More fuel loaded, fuel level "..turtle.getFuelLevel())
turtle.select(s)
return
end
end -- for
if first then
print("No fuel, load me up!")
first = false
end
sleep(1)
end -- while
end
end
--
-- Movement
--
-- move in any direction making sure we have fuel to go
function move(f)
refuel()
return f()
end
function stepDown()
if move(turtle.down) then
returnSteps = returnSteps - 1
return true
end
return false
end
function stepUp()
digUp()
if move(turtle.up) then
returnSteps = returnSteps + 1
return true
end
return false
end
--
-- Stash cleanup
--
function isJunk(item)
if item.name ~= floorBlock.name
and item.name ~= wallBlock.name
and item.name ~= roofBlock.name
and item.name ~= windowBlock.name
then
return true
end
return false
end
-- return slot index that can be dropped or 0 if none
function findJunkItemSlot()
for slot=1,16 do
if turtle.getItemCount(slot) > 0 then
item = turtle.getItemDetail(slot)
if isJunk(item) then
return slot
end
end
end
return 0
end
-- Determine if robot can take any more items of same type
function canStashFit(item)
for slot=1,16 do
if turtle.getItemCount(slot) == 0 then
return true
end
inSlot = turtle.getItemDetail(slot)
if inSlot.name == item.name
and inSlot.count < 64
then
return true
end
end
return false
end
-- inspect item and see if we can take it
function willFitItem(inspect)
local ok, item = inspect()
if not ok then return true end
return canStashFit(item)
end
-- Get rid of the bad items if there's no more space
function getRidOfJunk()
local s = turtle.getSelectedSlot()
while true do
slot = findJunkItemSlot()
if slot == 0 then
turtle.select(s)
return
end
turtle.select(slot)
turtle.drop()
end
end
--
-- Building operations
--
-- dig up until we can move in there
function digUp()
while turtle.detectUp() and not isBedrock(turtle.inspectUp) do
if not willFitItem(turtle.inspectUp) then
getRidOfJunk()
end
turtle.digUp()
sleep(.1) -- let falling stuff fall
end
end
-- dig down until we can move in there
function digDown()
while turtle.detectDown() and not isBedrock(turtle.inspectDown) do
if not willFitItem(turtle.inspectDown) then
getRidOfJunk()
end
turtle.digDown()
-- we ARE the falling stuff, no need to wait
end
end
-- dig forward until we can move in there
function digForward()
while turtle.detect() and not isBedrock(turtle.inspect) do
if not willFitItem(turtle.inspect) then
getRidOfJunk()
end
turtle.dig()
sleep(.1) -- let falling stuff fall
end
end
-- e.g. isBedrock(turtle.inspectDown)
function isBedrock(inspect)
local found, data = inspect()
if not found then return false end
return data.name == "minecraft:bedrock"
end
function selectBlock(block)
local first = true
local s = turtle.getSelectedSlot()
while true do
for slot=1,16 do
local item = turtle.getItemDetail(slot)
if item and item.name == block.name then
turtle.select(slot)
return
end
end -- for
if first then
print("Need more "..block.name.." blocks")
first = false
end
sleep(1)
end -- while
end
function placeOne(block)
local ok, item = turtle.inspectDown()
if ok and item.name == block.name then
return true
end
if turtle.detectDown() then
digDown()
end
selectBlock(block)
return turtle.placeDown()
end
function placeAndForward(block)
placeOne(block)
digForward()
move(turtle.forward)
end
function placeRowOf(block, steps)
for x=1,steps-1 do
placeAndForward(block)
end
placeOne(block)
end
-- Build a wall with window in it
-- Wall must be 10 steps or longer to have a window
function placeRowOfTwo(outerBlock, innerBlock, steps)
if steps < 10 then
placeRowOf(outerBlock, steps)
else
for x=1,3 do
placeAndForward(outerBlock)
end
for x=1,steps-6 do
placeAndForward(innerBlock)
end
for x=1,2 do
placeAndForward(outerBlock)
end
placeOne(outerBlock)
end
end
-- Build w x h area tile, finish in either top-right or bottom-right corner and return
-- "left" or "right" depending on where turtle needs to turn to continue building wall along
-- the W side.
function placeAreaOf(block, width, height)
for x=1,width do
placeRowOf(block, height)
if x ~= width then
if x % 2 == 1 then -- turn right
turtle.turnRight()
digForward()
move(turtle.forward)
turtle.turnRight()
else -- turn left
turtle.turnLeft()
digForward()
move(turtle.forward)
turtle.turnLeft()
end
end
end
if width % 2 == 1 then
return "left"
else
return "right"
end
end
function placeFloor(width, height)
return placeAreaOf(floorBlock, width, height)
end
function placeRoof(width, height)
return placeAreaOf(roofBlock, width, height)
end
function turn(rotation)
if rotation == "right" then
turtle.turnRight()
else
turtle.turnLeft()
end
end
function moveAlong(steps)
for x=1,steps do
digForward()
move(turtle.forward)
end
end
function placeSolidWall(width, height, rotation)
placeRowOf(wallBlock, height)
turn(rotation)
placeRowOf(wallBlock, width)
turn(rotation)
placeRowOf(wallBlock, height)
turn(rotation)
placeRowOf(wallBlock, width)
end
function placeWindowedWall(width, height, rotation)
placeRowOfTwo(wallBlock, windowBlock, height)
turn(rotation)
placeRowOfTwo(wallBlock, windowBlock, width)
turn(rotation)
placeRowOfTwo(wallBlock, windowBlock, height)
turn(rotation)
placeRowOfTwo(wallBlock, windowBlock, width)
end
function returnFromTileEndToOrigin(dir, width, height)
if dir == "right" then
turn("right")
moveAlong(width-1)
turn("right")
else
turn("left")
moveAlong(width-1)
turn("left")
moveAlong(height-1)
turn("right")
turn("right")
end
end
-- place w x d rooms with h height walls and repeated levels times
function placeRooms(width, depth, height, levels)
-- build first floor
local dir = placeFloor(width, depth)
for level=1,levels do
for wall=1,height do
stepUp()
turn(dir)
if wall > 1 and wall < height then
placeWindowedWall(depth, width, dir)
else
placeSolidWall(depth, width, dir)
end
end -- walls
stepUp()
-- follow along the wall to start point
returnFromTileEndToOrigin(dir, width, depth)
-- build roof
dir = placeRoof(width, depth)
end -- levels
-- Return to start point (we don't dig here because something adjacent may have already been built)
returnFromTileEndToOrigin(dir, width, depth)
move(turtle.back)
while returnSteps > 0 do
if not stepDown() then
return
end
end
end
--
-- main
--
function helpAndExit(msg)
print("Room builder")
print("------------")
print("room Width [Depth [Floors [Height]]]")
print("builds Width x Depth rooms, with number of Floors, with walls Height")
print("Depth equals Width if not specified, Floors default to 1, Height is 4")
print("Set Floors to 0 to build only floor tile")
print("\n"..msg)
print("------------")
exit()
end
local args = { ... }
if #args > 0 then
RoomWidth = tonumber(args[1])
RoomDepth = RoomWidth
end
if #args > 1 then
RoomDepth = tonumber(args[2])
end
if #args > 2 then
NumFloors = tonumber(args[3])
end
if #args > 3 then
WallHeight = tonumber(args[4])
end
if RoomWidth < 6 or RoomWidth > 64 then
helpAndExit("Invalid room width, enter 6..64 [default 16]")
end
if RoomDepth < 6 or RoomDepth > 64 then
helpAndExit("Invalid room depth, enter 6..64 [default 16]")
end
if WallHeight < 2 or WallHeight > 10 then
helpAndExit("Invalid wall height, enter 2..10 [default 4]")
end
if NumFloors < 0 or NumFloors > 10 then
helpAndExit("Invalid number of floors, enter 0..10 [default 1]")
end
placeRooms(RoomWidth, RoomDepth, WallHeight, NumFloors)
-- build cobble up-stairs of width 2 and X steps ahead
function selectCobbleSlot()
for slot=1,16 do
inSlot = turtle.getItemDetail(slot)
if inSlot and inSlot.name == "minecraft:cobblestone" then
turtle.select(slot)
return true
end
end
return false
end
function move(f)
if turtle.getFuelLevel() == 0 then
for slot=1,16 do
turtle.select(slot)
if turtle.refuel(0) then
turtle.refuel(1)
break
end
end
if turtle.getFuelLevel() == 0 then
print("No fuel, stopping")
return false
end
end
dig()
return f()
end
function dig()
while turtle.detect() do
turtle.dig()
end
while turtle.detectUp() do
turtle.digUp()
end
end
function placeOne()
if turtle.detectDown() then
turtle.digDown()
end
if not selectCobbleSlot() then
return false
end
return turtle.placeDown()
end
function placeTwoStep()
move(turtle.forward)
placeOne()
turtle.turnRight()
move(turtle.forward)
turtle.turnLeft()
placeOne()
move(turtle.up)
move(turtle.forward)
placeOne()
turtle.turnLeft()
move(turtle.forward)
turtle.turnRight()
placeOne()
return move(turtle.up)
end
local TotalSteps = 2
local args = { ... }
if #args > 0 then
TotalSteps = tonumber(args[1])
end
-- Validation
if TotalSteps > 300 then
print("too many steps, go below 300")
os.exit()
end
TotalSteps = TotalSteps / 2
for step=1,TotalSteps do
print("twostep "..step.." of "..TotalSteps)
if not placeTwoStep() then
break
end
end
print("returning to base")
TotalSteps = TotalSteps * 2
for step=1,TotalSteps do
move(turtle.back)
move(turtle.down)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment