Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Terraform v3.55
- -- By Everyone
- --
- -- Replaces blocks with other blocks while digging for resources.
- --
- -- Usage:
- -- terra [cycles] [dump] [quick [depth]]
- -- cycles - number of steps (cycles) to make.
- -- dump - literal string. Will dump inventory after each cycle.
- -- quick - literal string. Quickmode, default dig depth of 5.
- -- depth - number, valid with quick. Overrides default dig depth.
- --
- -- Configuration:
- -- Slot 1: surface
- -- Slot 2: subsurface on depth 2-4
- -- Slot 3, 4: filler, depth > 4
- -- land mapping class --------------------------------------------------------
- function LandMap()
- -- Maps existance of blocks.
- -- Each index represents one layer.
- -- If an index gets a mark,
- -- it means that there was a block on that depth.
- local map = {}
- -- current relative depth, we start at 0
- local depth = 0
- -- the depth the turtle was at when pitstop was called,
- -- can be treated as a depth save slot
- local lastPos = nil
- -- when turtle goes lower, new index is added to the landmap.
- local add = function()
- table.insert( map, false )
- end
- -- used to mark blocks on the landmap
- local mark = function()
- map[ depth ] = true
- end
- -- returns if there was a block on that depth
- local marked = function()
- return map[ depth ]
- end
- -- clears landmap after a cycle
- local clear = function()
- map = nil
- map = {}
- end
- local lower = function()
- depth = depth + 1
- end
- local higher = function()
- depth = depth - 1
- end
- local getDepth = function()
- return depth
- end
- -- save the depth the turtle is currently at
- local setLastPos = function()
- lastPos = depth
- end
- -- retrieve the depth the turtle was at
- local getLastPos = function()
- return lastPos
- end
- -- clear depth save slot.
- local resetLastPos = function()
- lastPos = nil
- end
- -- return methods for public use
- return {
- add = add,
- mark = mark,
- marked = marked,
- clear = clear,
- lower = lower,
- higher = higher,
- getDepth = getDepth,
- setLastPos = setLastPos,
- getLastPos = getLastPos,
- resetLastPos = resetLastPos
- }
- end -- function LandMap()
- landmap = LandMap() -- global landmap object
- -- inventory class ----------------------------------------------------------
- function Inventory()
- -- local inventory description
- local blocks = {}
- blocks["surface"] = {1}
- blocks["subsurface"] = {2}
- blocks["filling"] = {3,4}
- -- returns an array with slot numbers
- -- of given material.
- local slotNums = function( material )
- return blocks[ material ]
- end
- -- Checks if inventory is full
- local full = function()
- local bFull = true
- for n=5,16 do
- if turtle.getItemCount(n) == 0 then
- bFull = false
- end
- end
- if bFull then
- print( "No empty slots left." )
- end
- return bFull
- end
- -- selects a slot that should contain a block
- -- of given material.
- -- If no material is left, calls for a pitstop.
- -- This function is not exported,
- -- as it's only for internal use (by putBlock).
- local selectBlock = function( material )
- local slots = blocks[material]
- local outOfMaterial = true
- while outOfMaterial do
- for i=1, #slots do
- -- for internalRestock() to work
- -- there must be always one block left
- -- in each "config" stack.
- if turtle.getItemCount( slots[ i ] ) > 1 then -- here, the 1 instead of 0
- turtle.select( slots[ i ] )
- outOfMaterial = false
- break
- end
- end --end for
- if outOfMaterial then
- return false -- item was NOT found, could not select
- end
- end
- return true -- item was found, selection succesful
- end --selectBlock
- -- Tries to to restock missing materials
- -- out of those dugged out.
- local internalRestock = function( material )
- local slots = blocks[material]
- local restocked = false
- for i=1, #slots do
- for j=5, 16 do
- if turtle.getItemCount( j ) ~= 0 then
- turtle.select( j )
- if turtle.compareTo( slots[ i ] ) then
- turtle.transferTo( slots[ i ], 64 )
- restocked = true
- end -- if
- end --if
- end -- for j
- end -- for i (slots)
- return restocked
- end -- function internalRestock
- -- collects same items in larger stacks,
- -- to conserve space.
- local compact = function()
- local inv_cfg_rel_i = 5
- local vector = nil
- for i = 1, 16 do
- -- while compacting to config slots...
- if i < 5 then
- vector = inv_cfg_rel_i -- browse all slots every time
- -- when compacting other slots, use compact only
- -- starting from the next of the current slot
- else
- vector = i + 1
- end -- if (config slots)
- for j = vector, 16 do
- if turtle.getItemCount( j ) ~= 0 then
- turtle.select( j )
- if turtle.compareTo( i ) then
- turtle.transferTo( i, 64 )
- end -- if
- end -- if
- end -- for j
- end -- for i
- if not full() then
- return true -- Inventory got compact()ed, free slots gained.
- else
- return false -- Could not compact inventory more, need pitstop.
- end
- end -- function compact()
- -- puts a block.
- local putBlock = function()
- local putProcedure = function( material )
- -- try selecting a block until possible
- while not selectBlock( material ) do
- -- if block not selected then do internal restock
- if not internalRestock( material ) then
- -- if could not restock, do pitstop
- pitStop( material )
- end
- end
- turtle.placeDown()
- --[[ DEBUG CODE
- if not turtle.placeDown() then
- print( 'For some reason could not place '..material )
- end
- ]]--
- end -- putProcedure
- if landmap.getDepth() < 4 and landmap.getDepth() > 0 then
- putProcedure('subsurface')
- elseif landmap.getDepth() < 1 then
- putProcedure('surface')
- else
- putProcedure('filling')
- end
- end -- local putBlock
- -- Throws out all inventory slots,
- -- that are not used for configuration.
- local dump = function()
- for i=5,16 do
- turtle.select(i)
- turtle.dropUp(64)
- end
- end
- -- export methods for public usage
- return {
- slotNums = slotNums,
- putBlock = putBlock,
- full = full,
- dump = dump,
- internalRestock = internalRestock,
- compact = compact
- }
- end -- function Inventory()
- inv = Inventory()
- -----------------------------------------------------------------------------
- -- the digging part of the dig-fill-step cycle
- function dig()
- local hit_bedrock = false
- local bedrock_depth = nil
- -- BE AWARE! quickSteps and quickMode are global variables.
- -- If specified, program will run in quick mode
- -- and digging will stop at given depth (or when reaching bedrock)
- local inQuickMode = function()
- if quickMode then
- if landmap.getDepth() < quickSteps then
- -- continue digging
- return false
- else
- -- end digging
- return true
- end
- else
- -- end digging
- return false
- end
- end
- while not hit_bedrock and not inQuickMode() do --quickSteps is a global variable
- --add depth field to landmap
- landmap.add()
- --Move down, unless there's an obstacle
- if not turtle.down() then
- --print "Cannot go down."
- --if it's a Block obstacle
- if turtle.detectDown() then
- --print "Obstacle below."
- --then dig it, collect it and place a mark
- --for future reference
- if turtle.digDown() then
- --print "Obstacle neutralized."
- landmap.mark()
- --return false if Block was detected,
- --but cannot be dug (we've hit Bedrock)
- else
- bedrock_depth = landmap.getDepth()
- hit_bedrock = true
- --print("We've hit bedrock.")
- end
- --if cannot go down, but no Block obstacle was detected,
- --then there's a mob in the way we need to get rid of.
- else
- turtle.attackDown()
- end -- turtle.detectDown()
- -- check if inventory is full,
- -- compact if no slots left.
- -- if compact() returns false, then it means
- -- that even after compaction no space is left
- -- and a pitstop is needed.
- if inv.full() then
- if not inv.compact() then
- pitStop()
- end
- end
- else -- turtle.down()ed
- landmap.lower()
- end -- turtle.down()
- end -- while not bedrock
- end
- function fill()
- repeat --
- --Move up, unless there's an obstacle
- while not turtle.up() do
- --if it's a Block obstacle
- --remove it
- if turtle.detectUp() then
- turtle.digUp()
- --if not a block, then a mob,
- --so kill it
- else
- turtle.attackUp()
- end
- end
- landmap.higher()
- if landmap.marked() then
- inv.putBlock()
- end
- until landmap.getDepth() <= 0
- landmap.clear()
- end -- function fill()
- function refuelMode()
- if turtle.getFuelLevel() ~= "unlimited" then
- local minFuelLevel = 600
- while turtle.getFuelLevel() < minFuelLevel do
- nullDisplay()
- print('Not enough fuel, at least '..minFuelLevel - turtle.getFuelLevel()..' more is needed.')
- print('Please put more fuel in inventory.')
- for n=1,16 do
- local nCount = turtle.getItemCount(n)
- if nCount > 0 then
- turtle.select( n )
- turtle.refuel( nCount )
- end
- end --for
- sleep(5)
- end --while
- end
- nullDisplay()
- end
- function pitStop( sMaterialNeeded )
- landmap.setLastPos()
- --print( "PitStopping..." )
- goTo(0)
- nullDisplay()
- if sMaterialNeeded then
- print('Out of '..sMaterialNeeded..'.')
- print('Put '..sMaterialNeeded..' blocks in slot(s) '..strjoin( ', ', inv.slotNums( sMaterialNeeded ) ) )
- else
- printInstructions()
- end
- print "\nPress 'Enter' to continue."
- io.read()
- nullDisplay()
- goTo( landmap.getLastPos() )
- end -- function pitStop()
- -- if no steps are given to Terraform,
- -- this function is used after end of dig-fill-step cycle
- -- for asking if a the user wants to repeat the cycle
- function cycleRepeat()
- refuelMode()
- nullDisplay()
- printInstructions()
- print "\nWanna continue? (y/n)"
- while true do
- local event, param1 = os.pullEvent("char")
- if param1 == 'y' or param1 == 'Y' then
- return true
- elseif param1 == 'n' or param1 == 'N' then
- return false
- else
- sleep(1)
- end
- end
- nullDisplay()
- return
- end -- function cycleRepeat()
- -- simple function for printing instructions
- function printInstructions()
- print( "Fuel: "..turtle.getFuelLevel() )
- print "Put:"
- print "SURFACE in slot 1,"
- print "SUBSURFACE in slot 2,"
- print "FILLER in slot 3 and 4."
- end
- -- Concat the contents of the parameter list,
- -- separated by the string delimiter (just like in perl)
- -- example: strjoin(", ", {"Anna", "Bob", "Charlie", "Dolores"})
- function strjoin(delimiter, list)
- if #list == 0 then
- return ""
- end
- local string = list[1]
- for i = 2, #list do
- string = string .. delimiter .. list[i]
- end
- return string
- end --function strjoin
- -- goTo function, used to move turtle here and there
- -- in a quick fashion. Used by pitstop function.
- function goTo( howDeep )
- while landmap.getDepth() > howDeep do
- if turtle.up() then
- landmap.higher()
- elseif turtle.digUp() or turtle.attackUp() then
- sleep( 0.2 )
- end
- end
- while landmap.getDepth() < howDeep do
- if turtle.down() then
- landmap.lower()
- elseif turtle.digDown() or turtle.attackDown() then
- sleep( 0.2 )
- end
- end
- --print( "Got to position at depth "..landmap.getDepth() ) -- !DEBUG
- end
- -- step forward while keeping "feet on the ground" function
- function stepForward()
- while not turtle.forward() do
- if turtle.detect() then
- if not turtle.up() then
- print "Cannot go over obstacle."
- return false
- end
- end
- end
- while not turtle.detectDown() do
- while not turtle.down() do
- os.sleep( 0.5 )
- end
- end
- end -- function stepForward()
- function nullDisplay()
- term.clear()
- term.setCursorPos( 1, 1 )
- end
- --MAIN-PROGRAM--------------------------------------------
- -- Arguments handling
- tArgs = { ... }
- cycles = false
- quickMode = false
- quickSteps = false
- dumpInventory = false
- -- if there's at least one argument...
- if #tArgs >= 1 then
- for i=1, #tArgs do
- -- if it's a string == dump,
- -- then trow out inventory after each cycle
- if string.lower( tArgs[i] ) == 'dump' then
- dumpInventory = true
- elseif string.lower( tArgs[i] ) == 'quick' then
- quickMode = true
- quickSteps = 5
- -- if it's a number...
- elseif tonumber( tArgs[i] ) ~= nil then
- -- then if previous param was 'quick'
- -- then it's the number of quick steps to make
- if ( tArgs[ i - 1] ) ~= nil then
- if string.lower( tArgs[ i - 1] ) == 'quick' then
- quickSteps = tonumber( tArgs[i] )
- -- else it's the number of cycles.
- else
- cycles = tonumber( tArgs[i] )
- end
- else
- cycles = tonumber( tArgs[i] )
- end
- end -- if
- end -- for
- end -- if
- -- a single
- -- dig-fill-restock-stepForward
- -- cycle function
- function cycle()
- dig()
- fill()
- -- it's good to restock on everything we can
- -- if we are going to throw out everything
- if dumpInventory then
- inv.internalRestock('surface')
- inv.internalRestock('subsurface')
- inv.internalRestock('filling')
- inv.dump()
- end
- stepForward()
- end -- function cycle()
- -- MAIN LOOP
- refuelMode()
- if cycles then
- for i=0, cycles do
- cycle()
- end
- else
- repeat
- cycle()
- until not cycleRepeat()
- end
- print('Terraforming done.')
Advertisement
Add Comment
Please, Sign In to add comment