Guest User

Untitled

a guest
Apr 15th, 2013
633
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.42 KB | None | 0 0
  1. -- Terraform v3.55
  2. -- By Everyone
  3. --
  4. -- Replaces blocks with other blocks while digging for resources.
  5. --
  6. -- Usage:
  7. -- terra [cycles] [dump] [quick [depth]]
  8. -- cycles - number of steps (cycles) to make.
  9. -- dump - literal string. Will dump inventory after each cycle.
  10. -- quick - literal string. Quickmode, default dig depth of 5.
  11. -- depth - number, valid with quick. Overrides default dig depth.
  12. --
  13. -- Configuration:
  14. -- Slot 1: surface
  15. -- Slot 2: subsurface on depth 2-4
  16. -- Slot 3, 4: filler, depth > 4
  17.  
  18.  
  19. -- land mapping class --------------------------------------------------------
  20.  
  21. function LandMap()
  22.    
  23.     -- Maps existance of blocks.
  24.     -- Each index represents one layer.
  25.     -- If an index gets a mark,
  26.     -- it means that there was a block on that depth.
  27.     local map = {}
  28.    
  29.     -- current relative depth, we start at 0
  30.     local depth = 0
  31.    
  32.     -- the depth the turtle was at when pitstop was called,
  33.     -- can be treated as a depth save slot
  34.     local lastPos = nil
  35.    
  36.     -- when turtle goes lower, new index is added to the landmap.
  37.     local add = function()
  38.         table.insert( map, false )
  39.     end
  40.    
  41.     -- used to mark blocks on the landmap
  42.     local mark = function()
  43.         map[ depth ] = true
  44.     end
  45.    
  46.     -- returns if there was a block on that depth
  47.     local marked = function()
  48.         return map[ depth ]
  49.     end
  50.    
  51.     -- clears landmap after a cycle
  52.     local clear = function()
  53.         map = nil
  54.         map = {}
  55.     end
  56.    
  57.     local lower = function()
  58.         depth = depth + 1
  59.     end
  60.    
  61.     local higher = function()
  62.         depth = depth - 1
  63.     end
  64.    
  65.     local getDepth = function()
  66.         return depth
  67.     end
  68.    
  69.     -- save the depth the turtle is currently at
  70.     local setLastPos = function()
  71.         lastPos = depth
  72.     end
  73.    
  74.     -- retrieve the depth the turtle was at
  75.     local getLastPos = function()
  76.         return lastPos
  77.     end
  78.    
  79.     -- clear depth save slot.
  80.     local resetLastPos = function()
  81.         lastPos = nil
  82.     end
  83.  
  84.     -- return methods for public use
  85.     return {
  86.         add = add,
  87.         mark = mark,
  88.         marked = marked,
  89.         clear = clear,
  90.         lower = lower,
  91.         higher = higher,
  92.         getDepth = getDepth,
  93.         setLastPos = setLastPos,
  94.         getLastPos = getLastPos,
  95.         resetLastPos = resetLastPos
  96.     }
  97.  
  98. end -- function LandMap()
  99.  
  100. landmap = LandMap() -- global landmap object
  101.  
  102.  
  103.  
  104. -- inventory class ----------------------------------------------------------
  105.  
  106. function Inventory()
  107.  
  108.     -- local inventory description
  109.     local blocks = {}
  110.     blocks["surface"] = {1}
  111.     blocks["subsurface"] = {2}
  112.     blocks["filling"] = {3,4}
  113.  
  114.     -- returns an array with slot numbers
  115.     -- of given material.
  116.     local slotNums = function( material )
  117.         return blocks[ material ]
  118.     end
  119.  
  120.  
  121.     -- Checks if inventory is full
  122.     local full = function()
  123.         local bFull = true
  124.        
  125.         for n=5,16 do
  126.             if turtle.getItemCount(n) == 0 then
  127.                 bFull = false
  128.             end
  129.         end
  130.        
  131.         if bFull then
  132.             print( "No empty slots left." )
  133.         end
  134.  
  135.         return bFull
  136.     end
  137.  
  138.  
  139.     -- selects a slot that should contain a block
  140.     -- of given material.
  141.     -- If no material is left, calls for a pitstop.
  142.     -- This function is not exported,
  143.     -- as it's only for internal use (by putBlock).
  144.     local selectBlock = function( material )
  145.    
  146.         local slots = blocks[material]
  147.         local outOfMaterial = true
  148.  
  149.         while outOfMaterial do
  150.  
  151.             for i=1, #slots do
  152.  
  153.                 -- for internalRestock() to work
  154.                 -- there must be always one block left
  155.                 -- in each "config" stack.
  156.                 if turtle.getItemCount( slots[ i ] ) > 1 then -- here, the 1 instead of 0
  157.                     turtle.select( slots[ i ] )
  158.                     outOfMaterial = false
  159.                     break
  160.                 end
  161.  
  162.             end --end for
  163.  
  164.             if outOfMaterial then
  165.                 return false -- item was NOT found, could not select
  166.             end
  167.         end
  168.  
  169.         return true -- item was found, selection succesful
  170.     end --selectBlock
  171.  
  172.  
  173.     -- Tries to to restock missing materials
  174.     -- out of those dugged out.
  175.     local internalRestock = function( material )
  176.  
  177.         local slots = blocks[material]
  178.         local restocked = false
  179.  
  180.         for i=1, #slots do
  181.                
  182.             for j=5, 16 do
  183.  
  184.                 if turtle.getItemCount( j ) ~= 0 then
  185.                    
  186.                     turtle.select( j )
  187.                     if turtle.compareTo( slots[ i ] ) then
  188.                         turtle.transferTo( slots[ i ], 64 )
  189.                         restocked = true
  190.                     end -- if
  191.  
  192.                 end --if
  193.  
  194.             end -- for j
  195.  
  196.         end -- for i (slots)
  197.  
  198.         return restocked
  199.     end -- function internalRestock
  200.  
  201.  
  202.     -- collects same items in larger stacks,
  203.     -- to conserve space.
  204.     local compact = function()
  205.  
  206.         local inv_cfg_rel_i = 5
  207.         local vector = nil
  208.  
  209.         for i = 1, 16 do
  210.  
  211.             -- while compacting to config slots...
  212.             if i < 5 then
  213.                 vector = inv_cfg_rel_i -- browse all slots every time
  214.            
  215.             -- when compacting other slots, use compact only
  216.             -- starting from the next of the current slot
  217.             else
  218.                 vector = i + 1
  219.             end -- if (config slots)
  220.  
  221.             for j = vector, 16 do
  222.  
  223.                 if turtle.getItemCount( j ) ~= 0 then
  224.  
  225.                     turtle.select( j )
  226.                     if turtle.compareTo( i ) then
  227.                         turtle.transferTo( i, 64 )
  228.                     end -- if
  229.  
  230.                 end -- if
  231.  
  232.             end -- for j
  233.  
  234.         end -- for i
  235.  
  236.         if not full() then
  237.             return true -- Inventory got compact()ed, free slots gained.
  238.         else
  239.             return false -- Could not compact inventory more, need pitstop.
  240.         end
  241.  
  242.     end -- function compact()
  243.  
  244.  
  245.     -- puts a block.
  246.     local putBlock = function()
  247.  
  248.         local putProcedure = function( material )
  249.  
  250.             -- try selecting a block until possible
  251.             while not selectBlock( material ) do
  252.            
  253.                 -- if block not selected then do internal restock
  254.                 if not internalRestock( material ) then
  255.  
  256.                     -- if could not restock, do pitstop
  257.                     pitStop( material )
  258.                 end
  259.             end
  260.  
  261.             turtle.placeDown()
  262.  
  263.             --[[ DEBUG CODE
  264.             if not turtle.placeDown() then
  265.                 print( 'For some reason could not place '..material )
  266.             end
  267.              ]]--
  268.         end -- putProcedure
  269.  
  270.  
  271.         if landmap.getDepth() < 4 and landmap.getDepth() > 0 then
  272.             putProcedure('subsurface')
  273.  
  274.         elseif landmap.getDepth() < 1 then
  275.             putProcedure('surface')
  276.  
  277.         else
  278.             putProcedure('filling')
  279.         end
  280.  
  281.     end -- local putBlock
  282.  
  283.    
  284.     -- Throws out all inventory slots,
  285.     -- that are not used for configuration.
  286.     local dump = function()
  287.         for i=5,16 do
  288.             turtle.select(i)
  289.             turtle.dropUp(64)
  290.         end
  291.     end
  292.        
  293.    
  294.     -- export methods for public usage
  295.     return {
  296.         slotNums = slotNums,
  297.         putBlock = putBlock,
  298.         full = full,
  299.         dump = dump,
  300.         internalRestock = internalRestock,
  301.         compact = compact
  302.     }
  303.  
  304. end -- function Inventory()
  305.  
  306. inv = Inventory()
  307.  
  308. -----------------------------------------------------------------------------
  309.  
  310. -- the digging part of the dig-fill-step cycle
  311. function dig()
  312.  
  313.     local hit_bedrock = false
  314.     local bedrock_depth = nil
  315.  
  316.     -- BE AWARE! quickSteps and quickMode are global variables.
  317.     -- If specified, program will run in quick mode
  318.     -- and digging will stop at given depth (or when reaching bedrock)
  319.     local inQuickMode = function()
  320.        
  321.         if quickMode then
  322.             if landmap.getDepth() < quickSteps then
  323.                 -- continue digging
  324.                 return false
  325.             else
  326.                 -- end digging
  327.                 return true
  328.             end
  329.         else
  330.             -- end digging
  331.             return false
  332.         end
  333.     end
  334.  
  335.     while not hit_bedrock and not inQuickMode() do --quickSteps is a global variable
  336.  
  337.         --add depth field to landmap
  338.         landmap.add()
  339.  
  340.         --Move down, unless there's an obstacle
  341.         if not turtle.down() then
  342.             --print "Cannot go down."
  343.            
  344.             --if it's a Block obstacle
  345.             if turtle.detectDown() then
  346.                 --print "Obstacle below."
  347.                
  348.                 --then dig it, collect it and place a mark
  349.                 --for future reference
  350.                 if turtle.digDown() then
  351.                     --print "Obstacle neutralized."
  352.                     landmap.mark()
  353.                    
  354.                 --return false if Block was detected,
  355.                 --but cannot be dug (we've hit Bedrock)
  356.                 else
  357.                     bedrock_depth = landmap.getDepth()
  358.                     hit_bedrock = true
  359.                     --print("We've hit bedrock.")
  360.                 end
  361.  
  362.             --if cannot go down, but no Block obstacle was detected,
  363.             --then there's a mob in the way we need to get rid of.
  364.             else
  365.                 turtle.attackDown()
  366.             end -- turtle.detectDown()
  367.            
  368.            
  369.             -- check if inventory is full,
  370.             -- compact if no slots left.
  371.             -- if compact() returns false, then it means
  372.             -- that even after compaction no space is left
  373.             -- and a pitstop is needed.
  374.             if inv.full() then
  375.                 if not inv.compact() then
  376.                     pitStop()
  377.                 end
  378.             end
  379.            
  380.         else -- turtle.down()ed
  381.             landmap.lower()
  382.         end -- turtle.down()
  383.  
  384.     end -- while not bedrock
  385. end
  386.  
  387.  
  388. function fill()
  389.  
  390.     repeat --
  391.  
  392.         --Move up, unless there's an obstacle
  393.         while not turtle.up() do
  394.            
  395.             --if it's a Block obstacle
  396.             --remove it
  397.             if turtle.detectUp() then
  398.                 turtle.digUp()
  399.  
  400.             --if not a block, then a mob,
  401.             --so kill it
  402.             else
  403.                 turtle.attackUp()
  404.             end
  405.         end
  406.  
  407.         landmap.higher()
  408.        
  409.         if landmap.marked() then
  410.             inv.putBlock()
  411.         end
  412.  
  413.     until landmap.getDepth() <= 0
  414.    
  415.     landmap.clear()
  416.  
  417. end -- function fill()
  418.  
  419.  
  420.  
  421. function refuelMode()
  422.  
  423.     if turtle.getFuelLevel() ~= "unlimited" then
  424.  
  425.         local minFuelLevel = 600
  426.  
  427.         while turtle.getFuelLevel() < minFuelLevel do
  428.        
  429.             nullDisplay()
  430.             print('Not enough fuel, at least '..minFuelLevel - turtle.getFuelLevel()..' more is needed.')
  431.             print('Please put more fuel in inventory.')
  432.        
  433.             for n=1,16 do
  434.            
  435.                 local nCount = turtle.getItemCount(n)
  436.            
  437.                 if nCount > 0 then
  438.                     turtle.select( n )
  439.                     turtle.refuel( nCount )
  440.                 end
  441.                
  442.             end --for
  443.  
  444.             sleep(5)
  445.  
  446.         end --while
  447.     end
  448.    
  449.     nullDisplay()
  450. end
  451.  
  452.  
  453.  
  454. function pitStop( sMaterialNeeded )
  455.  
  456.     landmap.setLastPos()
  457.     --print( "PitStopping..." )
  458.     goTo(0)
  459.  
  460.     nullDisplay()
  461.     if sMaterialNeeded then
  462.         print('Out of '..sMaterialNeeded..'.')
  463.         print('Put '..sMaterialNeeded..' blocks in slot(s) '..strjoin( ', ', inv.slotNums( sMaterialNeeded ) ) )
  464.     else
  465.         printInstructions()
  466.     end
  467.  
  468.     print "\nPress 'Enter' to continue."
  469.     io.read()
  470.     nullDisplay()
  471.     goTo( landmap.getLastPos() )
  472.  
  473. end -- function pitStop()
  474.  
  475.  
  476.  
  477. -- if no steps are given to Terraform,
  478. -- this function is used after end of dig-fill-step cycle
  479. -- for asking if a the user wants to repeat the cycle
  480. function cycleRepeat()
  481.  
  482.     refuelMode()
  483.  
  484.     nullDisplay()
  485.     printInstructions()
  486.     print "\nWanna continue? (y/n)"
  487.        
  488.     while true do
  489.         local event, param1 = os.pullEvent("char")
  490.  
  491.         if param1 == 'y' or param1 == 'Y' then
  492.             return true
  493.         elseif param1 == 'n' or param1 == 'N' then
  494.             return false
  495.         else
  496.             sleep(1)
  497.         end
  498.  
  499.     end
  500.  
  501.     nullDisplay()
  502.     return
  503.  
  504. end -- function cycleRepeat()
  505.  
  506.  
  507.  
  508. -- simple function for printing instructions
  509. function printInstructions()
  510.     print( "Fuel: "..turtle.getFuelLevel() )
  511.     print "Put:"
  512.     print "SURFACE in slot 1,"
  513.     print "SUBSURFACE in slot 2,"
  514.     print "FILLER in slot 3 and 4."
  515. end
  516.  
  517.  
  518.  
  519. -- Concat the contents of the parameter list,
  520. -- separated by the string delimiter (just like in perl)
  521. -- example: strjoin(", ", {"Anna", "Bob", "Charlie", "Dolores"})
  522. function strjoin(delimiter, list)
  523.  
  524.     if #list == 0 then
  525.         return ""
  526.     end
  527.  
  528.     local string = list[1]
  529.  
  530.     for i = 2, #list do
  531.         string = string .. delimiter .. list[i]
  532.     end
  533.  
  534.     return string
  535.    
  536. end --function strjoin
  537.  
  538.  
  539.  
  540. -- goTo function, used to move turtle here and there
  541. -- in a quick fashion. Used by pitstop function.
  542. function goTo( howDeep )
  543.  
  544.     while landmap.getDepth() > howDeep do
  545.         if turtle.up() then
  546.             landmap.higher()
  547.         elseif turtle.digUp() or turtle.attackUp() then
  548.             sleep( 0.2 )
  549.         end
  550.     end
  551.    
  552.     while landmap.getDepth() < howDeep do
  553.         if turtle.down() then
  554.             landmap.lower()
  555.         elseif turtle.digDown() or turtle.attackDown() then
  556.             sleep( 0.2 )
  557.         end
  558.     end
  559.    
  560.     --print( "Got to position at depth "..landmap.getDepth() ) -- !DEBUG
  561. end
  562.  
  563.  
  564.  
  565. -- step forward while keeping "feet on the ground" function
  566. function stepForward()
  567.  
  568.     while not turtle.forward() do
  569.         if turtle.detect() then
  570.             if not turtle.up() then
  571.                 print "Cannot go over obstacle."
  572.                 return false
  573.             end
  574.         end
  575.     end
  576.    
  577.     while not turtle.detectDown() do
  578.         while not turtle.down() do
  579.             os.sleep( 0.5 )
  580.         end
  581.     end
  582.  
  583. end -- function stepForward()
  584.  
  585.  
  586.  
  587. function nullDisplay()
  588.     term.clear()
  589.     term.setCursorPos( 1, 1 )
  590. end
  591.  
  592.  
  593.  
  594. --MAIN-PROGRAM--------------------------------------------
  595.  
  596. -- Arguments handling
  597. tArgs = { ... }
  598. cycles = false
  599. quickMode = false
  600. quickSteps = false
  601. dumpInventory = false
  602.  
  603. -- if there's at least one argument...
  604. if #tArgs >= 1 then
  605.  
  606.     for i=1, #tArgs do
  607.  
  608.         -- if it's a string == dump,
  609.         -- then trow out inventory after each cycle
  610.         if string.lower( tArgs[i] ) == 'dump' then
  611.             dumpInventory = true
  612.        
  613.         elseif string.lower( tArgs[i] ) == 'quick' then
  614.             quickMode = true
  615.             quickSteps = 5
  616.        
  617.         -- if it's a number...
  618.         elseif tonumber( tArgs[i] ) ~= nil then
  619.  
  620.             -- then if previous param was 'quick'
  621.             -- then it's the number of quick steps to make
  622.             if ( tArgs[ i - 1] ) ~= nil then
  623.                 if string.lower( tArgs[ i - 1] ) == 'quick' then
  624.                     quickSteps = tonumber( tArgs[i] )
  625.                
  626.                 -- else it's the number of cycles.
  627.                 else
  628.                     cycles = tonumber( tArgs[i] )
  629.                 end
  630.             else
  631.                 cycles = tonumber( tArgs[i] )
  632.             end
  633.        
  634.         end -- if
  635.  
  636.     end -- for
  637.  
  638. end -- if
  639.  
  640.  
  641. -- a single
  642. -- dig-fill-restock-stepForward
  643. -- cycle function
  644. function cycle()
  645.  
  646.     dig()
  647.     fill()
  648.  
  649.     -- it's good to restock on everything we can
  650.     -- if we are going to throw out everything
  651.     if dumpInventory then
  652.         inv.internalRestock('surface')
  653.         inv.internalRestock('subsurface')
  654.         inv.internalRestock('filling')
  655.         inv.dump()
  656.     end
  657.  
  658.     stepForward()
  659.  
  660. end -- function cycle()
  661.  
  662.  
  663. -- MAIN LOOP
  664. refuelMode()
  665.  
  666. if cycles then
  667.    
  668.     for i=0, cycles do
  669.         cycle()
  670.     end
  671.  
  672. else
  673.  
  674.     repeat
  675.         cycle()
  676.     until not cycleRepeat()
  677.  
  678. end
  679.  
  680. print('Terraforming done.')
Advertisement
Add Comment
Please, Sign In to add comment