Krutoy242

Lake Dryer

May 31st, 2014
737
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- ********************************************************************************** --
  2. -- **                                                                              ** --
  3. -- **   Krutoy Turtle   (debug version)                                            ** --
  4. -- **   ----------------------------------------------------                       ** --
  5. -- **                                                                              ** --
  6. -- **   To start program, write in turte:                                          ** --
  7. -- **                                                                              ** --
  8. -- **    For stable version:                                                       ** --
  9. -- **   pastebin get YxWNp5bZ KrutoyTurtle                                         ** --
  10. -- **                                                                              ** --
  11. -- **    For developing version                                                    ** --
  12. -- **   pastebin get GHUv2MCR KrutoyTurtle                                         ** --
  13. -- **                                                                              ** --
  14. -- **   ----------------------------------------------------                       ** --
  15. -- **   Thanks for this peoples, i use theirs code:                                ** --
  16. -- **    - AustinKK (OreQuarry Turtle)                                             ** --
  17. -- **    - NitrogenFingers (NPaintPro)                                             ** --
  18. -- **   ----------------------------------------------------                       ** --
  19. -- **                                                                              ** --
  20. -- **                                                                              ** --
  21. -- ********************************************************************************** --
  22.  
  23. ------------------------------------------------------
  24. -- Download external libs                           --
  25. ------------------------------------------------------
  26. function runExternalCode(url)
  27.   local response = http.get(url)
  28.   local filetext = response.readAll()
  29.   local func,err=loadstring(filetext,"external_loaded")
  30.  
  31.   if not err then
  32.     setfenv(func,getfenv(1))
  33.     func()
  34.   else
  35.     error(err)
  36.   end
  37. end
  38.  
  39.  
  40. -- If you using IDE, you must load some files other way
  41. IDE = nil
  42. if(turtle) then
  43.   --runExternalCode('https://raw.githubusercontent.com/')
  44. else
  45.   IDE = true
  46.   dofile('src/ComputerCraft.lua')
  47. end
  48.  
  49.  
  50. ------------------------------------------------------
  51. -- Librarys                                         --
  52. ------------------------------------------------------
  53.  
  54.  
  55.  
  56. ------------------------------------------------------
  57. -- Filling function variables                       --
  58. ------------------------------------------------------
  59.  
  60. -- Main patterns, using in fill() function
  61. --  Numbers tell what the count block will be placed
  62. --  Exists: fillPattern[name][z][y][x]
  63. --  [space]: here will no block
  64. --  0: remove block here
  65. fillPattern = {
  66.   ['Plain'] =
  67.   { {'1'} },
  68.   ['BoxGrid'] =
  69.    {{'3222';
  70.      '2111';
  71.      '2111';
  72.      '2111';},
  73.     {'2111';
  74.      '1   ';
  75.      '1   ';
  76.      '1   ';},
  77.     {'2111';
  78.      '1   ';
  79.      '1   ';
  80.      '1   ';},
  81.     {'2111';
  82.      '1   ';
  83.      '1   ';
  84.      '1   ';}}
  85. }
  86.  
  87.  
  88. fillingFlags = {
  89.   'sides',          -- Making boxes without corners
  90.   'corners',        -- Making frames
  91.   'mirror',         -- Pattern texture will mirrored
  92.   'mirror -1',      -- Each mirrored pattern indexes will shif by one block
  93.   'mirror -1x',
  94.   'mirror -1y',
  95.   'mirror -1z',
  96.   'y->',            -- Build first x-z blocks, then go to next y layer
  97.   'x++', 'x--',     -- Shift next coord. Userful for stairs
  98.   'y++', 'y--',
  99.   'z++', 'z--',
  100.   'clear',          -- Replaces all pattern indexes to -1
  101.   'clearAllSkipped',-- Replaces all 0 to -1
  102.   'skipClearing',   -- Replaces all -1 to 0
  103.   'tunnel', 'tube'  -- tunnel without caps on start end end
  104. }
  105.  
  106.  
  107. ------------------------------------------------------
  108. -- Other variables                                  --
  109. ------------------------------------------------------
  110.  
  111. --A list of hexidecimal conversions from numbers to hex digits
  112. local hexnums = { [10] = "a", [11] = "b", [12] = "c", [13] = "d", [14] = "e" , [15] = "f" }
  113.  
  114. -- Enumeration to store the the different types of message that can be written
  115. messageLevel = { DEBUG=0, INFO=1, WARNING=2, ERROR=3, FATAL=4 }
  116.  
  117. -- Enumeration to store names for the 6 directions
  118. way = { FORWARD=0, RIGHT=1, BACK=2, LEFT=3, UP=4, DOWN=5 }
  119.  
  120. -- Enumeration of mining states
  121. miningState = { START=0, LAYER=1, EMPTYCHESTDOWN=2, EMPTYINVENTORY=3 }
  122.  
  123. local maximumGravelStackSupported = 25 -- The number of stacked gravel or sand blocks supported
  124. local turtleId -- For rednet
  125. local isWirelessTurtle
  126. local lastMoveNeededDig = true -- Determines whether the last move needed a dig first
  127. local logFileName = "KrutoyTurtle.log"
  128.  
  129. -- Variables to store the current location and orientation of the turtle. x is right, left, z is up, down and
  130. -- y is forward, back with relation to the starting orientation.
  131. local currOrient = way.FORWARD
  132. local currMiningState = miningState.START
  133. local currPos = vector.new() -- Start Pos is 0,0,0
  134.  
  135.  
  136. -- ********************************************************************************** --
  137. -- **                                                                              ** --
  138. -- **                                                                              ** --
  139. -- **                                                                              ** --
  140. -- **                                                                              ** --
  141. -- **                                                                              ** --
  142. -- **                                Utilities                                     ** --
  143. -- **                                                                              ** --
  144. -- **                                                                              ** --
  145. -- **                                                                              ** --
  146. -- **                                                                              ** --
  147. -- **                                                                              ** --
  148. -- ********************************************************************************** --
  149.  
  150. --===========================================================
  151. -- Make keys from values
  152. --===========================================================
  153. function makeSet (list)
  154.   local set = {}
  155.   for _, l in ipairs(list) do set[l] = true end
  156.   return set
  157. end
  158.  
  159. --===========================================================
  160. -- Clear screen and set cursor to start
  161. --===========================================================
  162. function clear()
  163.    term.clear()
  164.    term.setCursorPos (1,1)
  165. end
  166.  
  167.  
  168. --===========================================================
  169. -- Waiting untill user press key
  170. --===========================================================
  171. function pressAnyKey()
  172.   local event, param1 = os.pullEvent ("key")
  173. end
  174.  
  175. --===========================================================
  176. -- Writes requestText and wait while user press number key
  177. --===========================================================
  178. function readNumberParametr(requestText, from, to)
  179.   while true do
  180.      clear()
  181.      print (requestText)
  182.      local event, param1 = os.pullEvent ("char") -- limit os.pullEvent to the char event
  183.      local result = tonumber(param1)
  184.      if type(result) == 'number' and result >= from and result <= to then
  185.          return result
  186.      end
  187.   end
  188. end
  189.  
  190. --===========================================================
  191. -- Writes requestText and wait while user type
  192. -- several words or numbers
  193. --===========================================================
  194. function readTable(requestText, canBeSkipped, separator)
  195.   local resultStr = ''
  196.  
  197.   while true do
  198.     clear()
  199.     print(requestText)
  200.     resultStr = read()
  201.     if resultStr == '' and canBeSkipped == true then
  202.       return nil
  203.     elseif resultStr ~= '' then
  204.       local result = {}
  205.       local i=1
  206.       for v in string.gmatch(resultStr, separator) do
  207.         result[i] = v
  208.         i = i+1
  209.       end
  210.       return result
  211.     end
  212.   end
  213. end
  214.  
  215. --===========================================================
  216. -- Writes requestText and wait while user type
  217. -- several numbers
  218. --===========================================================
  219. function readTableOfNumbers(requestText, canBeSkipped, numbersCount, separator)
  220.   local resultStr = ''
  221.   local result = {}
  222.   for i=1,numbersCount do result[i]=0 end
  223.  
  224.  
  225.   while true do
  226.     local returnedResult = readTable(requestText, canBeSkipped, separator)
  227.    
  228.     if not returnedResult and canBeSkipped == true then
  229.       return result
  230.     elseif(returnedResult)then
  231.       local isAllNumbers = true
  232.       for i=1,numbersCount do
  233.         if(type(tonumber(returnedResult[i])) == "number") then
  234.           result[i] = tonumber(returnedResult[i])
  235.         else
  236.           print(returnedResult[i]..' is not number!')
  237.           sleep(1)
  238.           isAllNumbers=false
  239.         end
  240.       end
  241.      
  242.       if isAllNumbers == true then
  243.         return result
  244.       end
  245.     end
  246.   end
  247. end
  248.  
  249. --===========================================================
  250. -- Writes an output message
  251. -- Also, working with rednet
  252. --===========================================================
  253. function writeMessage(message, msgLevel)
  254.   print(message)
  255.  
  256.   -- If this turtle has a modem, then write the message to red net
  257.   if (isWirelessTurtle == true) then
  258.     if (turtleId == nil) then
  259.       rednet.broadcast(message)
  260.     else
  261.       -- Broadcast the message (prefixed with the turtle's id)
  262.       rednet.broadcast("[".. turtleId.."] "..message)
  263.       end
  264.     end
  265.  
  266.     if (logFileName ~= nil) then
  267.       -- Open file, write message and close file (flush doesn't seem to work!)
  268.     local outputFile
  269.     if (fs.exists(logFileName) == true) then
  270.       outputFile = io.open(logFileName, "a")
  271.     else
  272.       outputFile = io.open(logFileName, "w")
  273.     end
  274.  
  275.     outputFile:write(message)
  276.     outputFile:write("\n")
  277.     outputFile:close()
  278.   end
  279. end
  280.  
  281.  
  282. --===========================================================
  283. -- Reads the next number from a given file
  284. --===========================================================
  285. function readNumber(inputFile)
  286.  
  287.   local returnVal
  288.   local nextLine = inputFile.readLine()
  289.   if (nextLine ~= nil) then
  290.     returnVal = tonumber(nextLine)
  291.   end
  292.  
  293.   return returnVal
  294. end
  295.  
  296. --===========================================================
  297. -- Reads the next number from a given file
  298. --===========================================================
  299. function getChar(str, pos)
  300.   return string.sub(str, pos, pos)
  301. end
  302.  
  303.  
  304. --===========================================================
  305. -- Converts a hex digit into a colour value
  306. -- Params: hex:?string = the hex digit to be converted
  307. -- Returns:string A colour value corresponding to the hex, or nil if the character is invalid
  308. --===========================================================
  309. function getColourOf(hex)
  310.   local value = tonumber(hex, 16)
  311.   if not value then return nil end
  312.   value = math.pow(2,value)
  313.   return value
  314. end
  315.  
  316.  
  317. --===========================================================
  318. -- Converts a colour parameter into a single-digit hex coordinate for the colour
  319. -- Params: colour:int = The colour to be converted
  320. -- Returns:string A string conversion of the colour
  321. --===========================================================
  322. local function getHexOf(colour)
  323.   if not colour or not tonumber(colour) then
  324.     return " "
  325.   end
  326.   local value = math.log(colour)/math.log(2)
  327.   if value > 9 then
  328.     value = hexnums[value]
  329.   end
  330.   return value
  331. end
  332.  
  333.  
  334. --===========================================================
  335. -- Params: path:string = The path in which the file is located
  336. -- Returns:nil
  337. --===========================================================
  338. local function loadNFA(path)
  339.   if fs.exists(path) == false then
  340.     return nil
  341.   end
  342.  
  343.   local frames = { }
  344.   frames[1] = { }
  345.  
  346.   local file = io.open(path, "r" )
  347.   local sLine = file:read()
  348.   local z = 1
  349.   local y = 1
  350.   while sLine do
  351.     if sLine == "~" then
  352.       z = z + 1
  353.       frames[z] = { }
  354.       y = 1
  355.     else
  356.       if not frames[z][y] then frames[z][y]='' end
  357.       for i=1,#sLine do
  358.         frames[z][y] = frames[z][y] .. string.sub(sLine,i,i)
  359.       end
  360.       y = y+1
  361.     end
  362.     sLine = file:read()
  363.   end
  364.   file:close()
  365.  
  366.   return frames
  367. end
  368.  
  369.  
  370. -- ********************************************************************************** --
  371. -- **                                                                              ** --
  372. -- **                                                                              ** --
  373. -- **                                                                              ** --
  374. -- **                                                                              ** --
  375. -- **                                                                              ** --
  376. -- **                            Turtle wrappers                                   ** --
  377. -- **                                                                              ** --
  378. -- **                                                                              ** --
  379. -- **                                                                              ** --
  380. -- **                                                                              ** --
  381. -- **                                                                              ** --
  382. -- ********************************************************************************** --
  383.  
  384.  
  385. -- ********************************************************************************** --
  386. -- Turns the turtle (updating the current orientation at the same time)
  387. -- ********************************************************************************** --
  388. function turtleTurn(turnDir)
  389.  
  390.   if (turnDir == way.LEFT) then
  391.     if (currOrient == way.FORWARD) then
  392.       currOrient = way.LEFT
  393.     elseif (currOrient == way.LEFT) then
  394.       currOrient = way.BACK
  395.     elseif (currOrient == way.BACK) then
  396.       currOrient = way.RIGHT
  397.     elseif (currOrient == way.RIGHT) then
  398.       currOrient = way.FORWARD
  399.     else
  400.       writeMessage ("Invalid currOrient in turtleTurn function", messageLevel.ERROR)
  401.     end
  402.  
  403.  
  404.     -- Write the new orientation and turn
  405.     saveLocation()
  406.     turtle.turnLeft()
  407.  
  408.   elseif (turnDir == way.RIGHT) then
  409.     if (currOrient == way.FORWARD) then
  410.       currOrient = way.RIGHT
  411.     elseif (currOrient == way.LEFT) then
  412.       currOrient = way.FORWARD
  413.     elseif (currOrient == way.BACK) then
  414.       currOrient = way.LEFT
  415.     elseif (currOrient == way.RIGHT) then
  416.       currOrient = way.BACK
  417.     else
  418.       writeMessage ("Invalid currOrient in turtleTurn function", messageLevel.ERROR)
  419.     end
  420.  
  421.  
  422.     -- Write the new orientation and turn
  423.     saveLocation()
  424.     turtle.turnRight()
  425.   else
  426.     writeMessage ("Invalid turnDir in turtleTurn function", messageLevel.ERROR)
  427.   end
  428. end
  429.  
  430. -- ********************************************************************************** --
  431. -- Sets the turtle to a specific orientation, irrespective of its current orientation
  432. -- ********************************************************************************** --
  433. function turtleSetOrientation(newOrient)
  434.  
  435.   -- Already turned
  436.   if (currOrient == newOrient) then return true end
  437.  
  438.  
  439.   -- Wrong parameters - we cant turn up or down
  440.   if newOrient < 0 or newOrient > way.LEFT then
  441.     writeMessage ("Invalid newOrient in turtleSetOrientation function", messageLevel.DEBUG)
  442.     return false
  443.   end
  444.  
  445.   local turn = currOrient - newOrient
  446.   local turnFnc
  447.  
  448.   if turn==1 or turn==-3 then
  449.     turnFnc = turtle.turnLeft
  450.   else
  451.     turnFnc = turtle.turnRight
  452.   end
  453.  
  454.   turn = math.abs(turn)
  455.   if(turn==3) then turn=1 end
  456.  
  457.   currOrient = newOrient
  458.  
  459.  
  460.   for i=1, turn do
  461.     turnFnc()
  462.   end
  463.  
  464. end
  465.  
  466. --===========================================================
  467. -- Dig, depending on direction
  468. --===========================================================
  469. function turtleDig(direction)
  470.   if (direction == nil) or (direction == way.FORWARD) then
  471.     return turtle.dig()
  472.   elseif(direction == way.DOWN) then
  473.     return turtle.digDown()
  474.   elseif(direction == way.UP) then
  475.     return turtle.digUp()
  476.   else
  477.     writeMessage('Wrong direction for turtleDig()', messageLevel.ERROR)
  478.     return false
  479.   end
  480. end
  481.  
  482. -- ********************************************************************************** --
  483. -- Generic function to move the Turtle (pushing through any gravel or other
  484. -- things such as mobs that might get in the way).
  485. --
  486. -- The only thing that should stop the turtle moving is bedrock. Where this is
  487. -- found, the function will return after 15 seconds returning false
  488. -- ********************************************************************************** --
  489. function moveTurtle(moveFn, detectFn, digFn, attackFn, compareFn, suckFn, maxDigCount, newX, newY, newZ)
  490.  
  491.   local moveSuccess = false
  492.  
  493.  
  494.   local prevX, prevY, prevZ
  495.   prevX = currPos.x
  496.   prevY = currPos.y
  497.   prevZ = currPos.z
  498.  
  499.  
  500.   -- Flag to determine whether digging has been tried yet. If it has
  501.   -- then pause briefly before digging again to allow sand or gravel to
  502.   -- drop
  503.   local digCount = 0
  504.  
  505.     if (lastMoveNeededDig == false) then
  506.       -- Didn't need to dig last time the turtle moved, so try moving first
  507.  
  508.       currPos.x = newX
  509.       currPos.y = newY
  510.       currPos.z = newZ
  511.  
  512.       moveSuccess = moveFn()
  513.  
  514.       -- If move failed, update the co-ords back to the previous co-ords
  515.       if (moveSuccess == false) then
  516.         currPos.x = prevX
  517.         currPos.y = prevY
  518.         currPos.z = prevZ
  519.       end
  520.  
  521.       -- Don't need to set the last move needed dig. It is already false, if
  522.       -- move success is now true, then it won't be changed
  523.     else
  524.       -- Try to dig (without doing a detect as it is quicker)
  525.       local digSuccess = digFn()
  526.       if (digSuccess == true) then
  527.         digCount = 1
  528.       end
  529.  
  530.       currPos.x = newX
  531.       currPos.y = newY
  532.       currPos.z = newZ
  533.  
  534.       moveSuccess = moveFn()
  535.  
  536.       if (moveSuccess == true) then
  537.         lastMoveNeededDig = digSuccess
  538.       else
  539.         currPos.x = prevX
  540.         currPos.y = prevY
  541.         currPos.z = prevZ
  542.       end
  543.  
  544.     end
  545.  
  546.     -- Loop until we've successfully moved
  547.     if (moveSuccess == false) then
  548.       while ((moveSuccess == false) and (digCount < maxDigCount)) do
  549.  
  550.         -- If there is a block in front, dig it
  551.         if (detectFn() == true) then
  552.        
  553.             -- If we've already tried digging, then pause before digging again to let
  554.             -- any sand or gravel drop, otherwise check for a chest before digging
  555.             if(digCount == 0) then
  556.            
  557.             else
  558.               sleep(0.1)
  559.             end
  560.  
  561.             digFn()
  562.             digCount = digCount + 1
  563.         else
  564.            -- Am being stopped from moving by a mob, attack it
  565.            attackFn()
  566.         end
  567.  
  568.         currPos.x = newX
  569.         currPos.y = newY
  570.         currPos.z = newZ
  571.  
  572.         -- Try the move again
  573.         moveSuccess = moveFn()
  574.  
  575.         if (moveSuccess == false) then
  576.           currPos.x = prevX
  577.           currPos.y = prevY
  578.           currPos.z = prevZ
  579.         end
  580.       end
  581.  
  582.       if (digCount == 0) then
  583.         lastMoveNeededDig = false
  584.       else
  585.         lastMoveNeededDig = true
  586.       end
  587.     end
  588.  
  589.   -- Return the move success
  590.   return moveSuccess
  591. end
  592.  
  593. -- ********************************************************************************** --
  594. -- Move the turtle forward one block (updating the turtle's position)
  595. -- ********************************************************************************** --
  596. function turtleForward()
  597.  
  598.   -- Determine the new co-ordinate that the turtle will be moving to
  599.   local newX, newY
  600.  
  601.   -- Update the current co-ordinates
  602.   if (currOrient == way.FORWARD) then
  603.     newY = currPos.y + 1
  604.     newX = currPos.x
  605.   elseif (currOrient == way.LEFT) then
  606.     newX = currPos.x - 1
  607.     newY = currPos.y
  608.   elseif (currOrient == way.BACK) then
  609.     newY = currPos.y - 1
  610.     newX = currPos.x
  611.   elseif (currOrient == way.RIGHT) then
  612.     newX = currPos.x + 1
  613.     newY = currPos.y
  614.   else
  615.     writeMessage ("Invalid currOrient in turtleForward function", messageLevel.ERROR)
  616.   end
  617.  
  618.   local returnVal = moveTurtle(turtle.forward, turtle.detect, turtle.dig, turtle.attack, turtle.compare, turtle.suck, maximumGravelStackSupported, newX, newY, currPos.z)
  619.  
  620.  
  621.   return returnVal
  622. end
  623.  
  624. -- ********************************************************************************** --
  625. -- Move the turtle up one block (updating the turtle's position)
  626. -- ********************************************************************************** --
  627. function turtleUp()
  628.  
  629.   local returnVal = moveTurtle(turtle.up, turtle.detectUp, turtle.digUp, turtle.attackUp, turtle.compareUp, turtle.suckUp, maximumGravelStackSupported, currPos.x, currPos.y, currPos.z + 1)
  630.  
  631.   return returnVal
  632. end
  633.  
  634. -- ********************************************************************************** --
  635. -- Move the turtle down one block (updating the turtle's position)
  636. -- ********************************************************************************** --
  637. function turtleDown()
  638.  
  639.   local returnVal = moveTurtle(turtle.down, turtle.detectDown, turtle.digDown, turtle.attackDown, turtle.compareDown, turtle.suckDown, 1, currPos.x, currPos.y, currPos.z - 1)
  640.  
  641.   return returnVal
  642. end
  643.  
  644. -- ********************************************************************************** --
  645. -- Move the turtle back one block (updating the turtle's position)
  646. -- ********************************************************************************** --
  647. function turtleBack(doNotTurnBack)
  648.  
  649.   -- Assume that the turtle will move, and switch the co-ords back if it doesn't
  650.   -- (do this so that we can write the co-ords to a file before moving)
  651.   local newX, newY
  652.   local prevX, prevY
  653.   prevX = currPos.x
  654.   prevY = currPos.y
  655.  
  656.   -- Update the current co-ordinates
  657.   if (currOrient == way.FORWARD) then
  658.     newY = currPos.y - 1
  659.     newX = currPos.x
  660.   elseif (currOrient == way.LEFT) then
  661.     newX = currPos.x + 1
  662.     newY = currPos.y
  663.   elseif (currOrient == way.BACK) then
  664.     newY = currPos.y + 1
  665.     newX = currPos.x
  666.   elseif (currOrient == way.RIGHT) then
  667.     newX = currPos.x - 1
  668.     newY = currPos.y
  669.   else
  670.     writeMessage ("Invalid currOrient in turtleBack function", messageLevel.ERROR)
  671.   end
  672.  
  673.   -- First try to move back using the standard function
  674.   currPos.x = newX
  675.   currPos.y = newY
  676.   local returnVal = turtle.back()
  677.  
  678.   if (returnVal == false) then
  679.     -- Didn't move. Reset the co-ordinates to the previous value
  680.     currPos.x = prevX
  681.     currPos.y = prevY
  682.  
  683.     turtle.turnRight()
  684.     turtle.turnRight()
  685.  
  686.     -- Try to move by using the forward function (note, the orientation will be set as
  687.     -- the same way as this function started because if the function stops, that is the
  688.     -- way that we want to consider the turtle to be pointing)
  689.     returnVal = moveTurtle(turtle.forward, turtle.detect, turtle.dig, turtle.attack, turtle.compare, turtle.suck, maximumGravelStackSupported, newX, newY, currPos.z)
  690.  
  691.     if not doNotTurnBack then
  692.       turtle.turnRight()
  693.       turtle.turnRight()
  694.     end
  695.   end
  696.    
  697.   return returnVal
  698. end
  699.  
  700.  
  701. --===========================================================
  702. -- Move turtle on needed position
  703. -- Simple move by x, then y, then z
  704. --===========================================================
  705. function turtleGoTo(x,y,z)
  706.   if not x then x=currPos.x end
  707.   if not y then y=currPos.y end
  708.   if not z then z=currPos.z end
  709.  
  710.   local targetVec = vector.new(x,y,z) - currPos
  711.  
  712.  
  713.   -- X
  714.   if (targetVec.x<0 and currOrient==way.RIGHT)   or
  715.      (targetVec.x>0 and currOrient==way.LEFT)    then
  716.      while currPos.x ~= x do
  717.        turtleBack(true)
  718.      end
  719.   end
  720.  
  721.   while (x<currPos.x) do
  722.     turtleSetOrientation(way.LEFT)
  723.     turtleForward()
  724.   end
  725.   while (x>currPos.x) do
  726.     turtleSetOrientation(way.RIGHT)
  727.     turtleForward()
  728.   end
  729.  
  730.  
  731.   -- Y
  732.   if(targetVec.y<0 and currOrient==way.FORWARD) or
  733.     (targetVec.y>0 and currOrient==way.BACK)    then
  734.      while currPos.y ~= y do
  735.        turtleBack(true)
  736.      end
  737.   end
  738.  
  739.   while (y<currPos.y) do
  740.     turtleSetOrientation(way.BACK)
  741.     turtleForward()
  742.   end
  743.   while (y>currPos.y) do
  744.     turtleSetOrientation(way.FORWARD)
  745.     turtleForward()
  746.   end
  747.  
  748.  
  749.   -- Z
  750.   while (z<currPos.z) do
  751.     turtleDown()
  752.   end
  753.   while (z>currPos.z) do
  754.     turtleUp()
  755.   end
  756. end
  757.  
  758. --===========================================================
  759. -- Move turtle on needed point
  760. --===========================================================
  761. function turtleGoToP(point)
  762.   turtleGoTo(point.x, point.y, point.z)
  763. end
  764.  
  765. --===========================================================
  766. -- Just leave numbers in pattern, if in blacklist is 0
  767. --===========================================================
  768. function selectPatternByBlacklist(pattern, blacklist)
  769.   local resultPattern = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
  770.   for i=1, 16 do
  771.       if(blacklist[i] == 0) then resultPattern[i] = pattern[i] end
  772.   end
  773.   return resultPattern
  774. end
  775.  
  776. --===========================================================
  777. -- Searching if wee have needed item in inventory
  778. --===========================================================
  779. function findInSlotsArrayByPattern(arr, n, blacklist)
  780.   blacklist = blacklist or {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
  781.  
  782.   -- Set indexes to 0 if blacklist here is 1
  783.   local filteredArr = selectPatternByBlacklist(arr, blacklist)
  784.  
  785.   for i=1, 16 do
  786.     if(filteredArr[i] == n) and (turtle.getItemCount(i) > 0) then
  787.       return i
  788.     end
  789.   end
  790.   return 0
  791. end
  792.  
  793.  
  794. -- ********************************************************************************** --
  795. -- **                                                                              ** --
  796. -- **                                                                              ** --
  797. -- **                                                                              ** --
  798. -- **                                                                              ** --
  799. -- **                                                                              ** --
  800. -- **                                PROGRAMS                                      ** --
  801. -- **                                                                              ** --
  802. -- **                                                                              ** --
  803. -- **                                                                              ** --
  804. -- **                                                                              ** --
  805. -- **                                                                              ** --
  806. -- ********************************************************************************** --
  807.  
  808.  
  809. -- ********************************************************************************** --
  810. -- Go to the storage and suck needed blocks. Storage must be defined
  811. -- ********************************************************************************** --
  812. function reloadForFilling(slotsPattern, blacklistPattern)
  813.  
  814.   local reloadedPattern = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
  815.  
  816.   -- Default blacklist. No thrash to drop
  817.   if(blacklistPattern==nil) then blacklistPattern = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} end
  818.  
  819.   -- First, unload blacklisted slotls
  820.   -- This is blocks that we dont using for building
  821.   for i=1, 16 do
  822.     if( blacklistPattern[i] > 0) then
  823.       turtleGoTo(0,0,0)
  824.       turtleSetOrientation(way.LEFT)
  825.      
  826.       turtle.select(i)
  827.       turtle.drop()
  828.     end
  829.   end
  830.  
  831.   -- Then move to storages and take blocks
  832.   for i=1, 16 do
  833.     local itemSpace = turtle.getItemSpace(i)
  834.     if( itemSpace > 0  and (slotsPattern[i] > 0)) then
  835.       turtleGoTo((slotsPattern[i]-1)*2, 0, 0)
  836.       turtleSetOrientation(way.BACK)
  837.       turtle.select(i)
  838.       if( turtle.suck(itemSpace) ) then
  839.         -- Yes, we sucked something. Lets write it in pattern
  840.         reloadedPattern[i] = 1
  841.       end
  842.     end
  843.   end
  844.  
  845.   return reloadedPattern
  846. end
  847.  
  848. -- ********************************************************************************** --
  849. -- Place item in front of turtle. Check if item already placed.
  850. -- ********************************************************************************** --
  851. function placeBlock(itemSlot, direction)
  852.  
  853.   local detectFnc, compareFnc, placeFnc, attackFnc =
  854.         turtle.detect, turtle.compare, turtle.place,turtle.attack
  855.  
  856.   if( direction == way.UP ) then
  857.     detectFnc, compareFnc, placeFnc, attackFnc =
  858.     turtle.detectUp, turtle.compareUp, turtle.placeUp, turtle.attackUp
  859.   elseif( direction == way.DOWN )then
  860.     detectFnc, compareFnc, placeFnc, attackFnc =
  861.     turtle.detectDown, turtle.compareDown, turtle.placeDown, turtle.attackDown
  862.   end
  863.  
  864.   -- slotsPattern is array of 16 nubbers that represent
  865.   -- what kind of blocks lying in what kind of
  866.   if(itemSlot == nil) then
  867.     selectNonEmptySlot()
  868.   else
  869.     turtle.select(itemSlot)
  870.   end
  871.  
  872.   local placeSucces = false
  873.   local digCount = 0
  874.   local maxDigCount = 20
  875.  
  876.  
  877.   -- Check if there is already item  then try to place
  878.   placeSucces = placeFnc()
  879.  
  880.   if((not placeSucces) and detectFnc()) then
  881.     if(compareFnc()) then
  882.       -- Item that we must set already here
  883.       return true
  884.     else
  885.       -- There is something else. Dig/Attack and place item
  886.       turtleDig(direction)
  887.       digCount = digCount + 1
  888.     end
  889.   end
  890.  
  891.   -- Now try to place item until item will placed
  892.   while ((placeSucces == false) and (digCount < maxDigCount)) do
  893.     if (detectFnc()) then
  894.       if(digCount > 0) then
  895.         sleep(0.1)
  896.       end
  897.       turtleDig(direction)
  898.       digCount = digCount + 1
  899.     else
  900.        -- Am being stopped from moving by a mob, attack it
  901.        attackFnc()
  902.     end
  903.     -- Try the place again
  904.     placeSucces = placeFnc()
  905.   end
  906.  
  907.   return placeSucces
  908. end
  909.  
  910. -- ********************************************************************************** --
  911. -- Select non-empty slot
  912. -- ********************************************************************************** --
  913. function selectNonEmptySlot()
  914.   for i=1, 16 do
  915.     if( turtle.getItemCount(i) > 0) then
  916.       turtle.select(i)
  917.       return true
  918.     end
  919.   end
  920.   return false
  921. end
  922.  
  923. -- ********************************************************************************** --
  924. -- Get slot pattern.
  925. -- Returning array(16) that represent indexes in slots
  926. -- ********************************************************************************** --
  927. function getSlotsPattern()
  928.   local ptattern = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} -- Standart pattern. All slots empty
  929.   local lastUnemptySlot = 0
  930.   local lastEnum = 1
  931.  
  932.   for i=1, 16 do
  933.     turtle.select(i)
  934.     if( turtle.getItemCount(i) > 0) then
  935.       if (lastUnemptySlot == 0) then
  936.         lastUnemptySlot = i
  937.       elseif (i>1) and (turtle.compareTo(lastUnemptySlot) == false) then
  938.         lastEnum = lastEnum + 1
  939.         lastUnemptySlot = i
  940.       end
  941.      
  942.       ptattern[i] = lastEnum
  943.     end
  944.   end
  945.   return ptattern
  946. end
  947.  
  948.  
  949. -- ********************************************************************************** --
  950. -- Fill territory by blocks pattern
  951. --
  952. -- ********************************************************************************** --
  953. function fill(sizeX, sizeY, sizeZ, patternId, pos, isGoBackAfterFill, fillFlags)
  954.  
  955.   -- ==============================
  956.   -- Variables
  957.   -- ==============================
  958.   if not pos then pos = vector.new() end -- Default position: zero
  959.  
  960.   if not patternId then patternId = 'plain' end -- Default pattern index - plain fill
  961.   if not isGoBackAfterFill then isGoBackAfterFill = true end -- Default returning - yes, go back
  962.  
  963.   -- Pattern sizes per axis
  964.   local ptSzX = #fillPattern[patternId][1][1]
  965.   local ptSzY = #fillPattern[patternId][1]
  966.   local ptSzZ = #fillPattern[patternId]
  967.  
  968.   -- There we will storage what slots was deplited, out of building blocks
  969.   -- 0: slot in use, have blocks.
  970.   -- 1: slot deplited, haven't blocks or have thrash
  971.   local blacklistPattern = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
  972.  
  973.   local totalVolume = sizeX*sizeY*sizeZ -- Total volume of blocks
  974.   local vol = {{{}}} -- 3d array of whole volume filling territory
  975.  
  976.  
  977.   -- Statistics
  978.   local totalBlocksToPlace    = 0  -- Total count of blocks that must be placed
  979.   local totalBlocksCountArray = {} -- Blocks count by indexes
  980.   local totalFuelNeeded       = 0
  981.  
  982.  
  983.   -- ==============================
  984.   -- Preparing
  985.   -- At first, we must make a large
  986.   -- array of all blocks in volume
  987.   -- ==============================
  988.   for O=0, totalVolume-1 do
  989.     local u, v, w
  990.     u = math.floor(O/(sizeX*sizeY)) -- z
  991.     v = math.floor(O/sizeX) % sizeY -- y
  992.     w = math.floor(O%sizeX)         -- x
  993.    
  994.  
  995.     -- Pattern picker must think we are on this 'imagined' or 'fabled' positions
  996.     local fabled_u, fabled_v, fabled_w = u,v,w
  997.     if(fillFlags['mirror -1'] or fillFlags['mirror -1z']) then
  998.       fabled_u = u + math.floor( (u+ptSzZ-1) / (ptSzZ*2-1) )
  999.     end
  1000.     if(fillFlags['mirror -1'] or fillFlags['mirror -1y']) then
  1001.       fabled_v = v + math.floor( (v+ptSzY-1) / (ptSzY*2-1) )
  1002.     end
  1003.     if(fillFlags['mirror -1'] or fillFlags['mirror -1x']) then
  1004.       fabled_w = w + math.floor( (w+ptSzX-1) / (ptSzX*2-1) )
  1005.     end
  1006.  
  1007.     -- Compute pattern array indexes. Place on pattern that we want to take
  1008.     local ptX, ptY, ptZ = fabled_w%ptSzX, fabled_v%ptSzY, fabled_u%ptSzZ
  1009.    
  1010.     -- Flag "mirror" must mirrored all coordinates on even step
  1011.     if(fillFlags['mirror'] or fillFlags['mirror -1'] or fillFlags['mirror -1x'] or
  1012.        fillFlags['mirror -1y'] or fillFlags['mirror -1z']) then
  1013.       if (math.floor(fabled_w/ptSzX) % 2) == 1 then ptX = ptSzX-ptX-1 end
  1014.       if (math.floor(fabled_v/ptSzY) % 2) == 1 then ptY = ptSzY-ptY-1 end
  1015.       if (math.floor(fabled_u/ptSzZ) % 2) == 1 then ptZ = ptSzZ-ptZ-1 end
  1016.     end
  1017.  
  1018.  
  1019.     -- Get block index from pattern, demands on position of turtle
  1020.     local blockIndex = tonumber(getChar(fillPattern[patternId][ptZ+1][ptY+1], ptX+1))
  1021.    
  1022.     -- When we use 'sides' or 'corners' flags, we avoid all blocks inside volume
  1023.     if fillFlags['sides'] or fillFlags['corners'] then
  1024.       if(u>0 and u<sizeZ-1) and (v>0 and v<sizeY-1) and (w>0 and w<sizeX-1) then
  1025.         blockIndex = 0
  1026.       end
  1027.     end
  1028.    
  1029.     -- If only 'sides' flag enabled, clear all corners
  1030.     if fillFlags['sides'] and not fillFlags['corners'] then
  1031.       if not(((u>0 and u<sizeZ-1) and (v>0 and v<sizeY-1)) or
  1032.              ((u>0 and u<sizeZ-1) and (w>0 and w<sizeX-1)) or
  1033.              ((w>0 and w<sizeX-1) and (v>0 and v<sizeY-1))) then
  1034.         blockIndex = 0
  1035.       end
  1036.     end
  1037.    
  1038.     -- If only 'corners', clear all sides
  1039.     if fillFlags['corners'] and not fillFlags['sides'] then
  1040.       if not(((u==0 or u==sizeZ-1) and (v==0 or v==sizeY-1)) or
  1041.              ((u==0 or u==sizeZ-1) and (w==0 or w==sizeX-1)) or
  1042.              ((w==0 or w==sizeX-1) and (v==0 or v==sizeY-1))) then
  1043.         blockIndex = 0
  1044.       end
  1045.     end
  1046.     if fillFlags['tunnel'] and (w==0 or w==sizeX-1) and (u>0 and u<sizeZ-1) and (v>0 and v<sizeY-1) then
  1047.       blockIndex = 0
  1048.     end
  1049.     if fillFlags['tube'] and (u==0 or u==sizeZ-1) and (w>0 and w<sizeX-1) and (v>0 and v<sizeY-1) then
  1050.       blockIndex = 0
  1051.     end
  1052.     if fillFlags['clearAllSkipped'] then if blockIndex== nil then blockIndex = 0 end end
  1053.     if fillFlags['skipClearing']    then if blockIndex==   0 then blockIndex = nil end end
  1054.    
  1055.     -- Clear all blocks, ignoring any pattern
  1056.     if fillFlags['clear'] then blockIndex = 0 end
  1057.  
  1058.  
  1059.     -- Add tables if they are not defined
  1060.     if not vol[u]       then vol[u]       = {} end
  1061.     if not vol[u][v]    then vol[u][v]    = {} end
  1062.     if not vol[u][v][w] then vol[u][v][w] = {} end
  1063.    
  1064.     -- Put block index in volume array
  1065.     vol[u][v][w] = blockIndex
  1066.    
  1067.     -- Statistics
  1068.     if blockIndex ~= nil and blockIndex ~= 0 then
  1069.    
  1070.       -- Create key for new type
  1071.       if not totalBlocksCountArray[blockIndex] then totalBlocksCountArray[blockIndex] = 0 end
  1072.    
  1073.       -- Increment counters
  1074.       if(blockIndex>0)then
  1075.         totalBlocksToPlace = totalBlocksToPlace + 1
  1076.         totalBlocksCountArray[blockIndex] = totalBlocksCountArray[blockIndex] + 1
  1077.       end
  1078.     end
  1079.   end
  1080.  
  1081.   -- More statistics
  1082.   totalFuelNeeded = sizeX*sizeY*(2 + math.floor(sizeZ/3))
  1083.  
  1084.  
  1085.  
  1086.   -- ==============================
  1087.   -- Info screen
  1088.   -- ==============================
  1089.  
  1090.   clear()
  1091.   print('---------INFO---------:\n'..
  1092.   'Minimum fuel needed:   '..totalFuelNeeded)
  1093.  
  1094.   -- Print how much we need of blocks by each type
  1095.   for k,v in pairs(totalBlocksCountArray) do
  1096.     local stacks   = math.floor(v/64)
  1097.     local modStacks= v%64
  1098.     print(' #'..k..': '..((stacks>0) and stacks..'x64' or '')..
  1099.       ((stacks>0 and modStacks>0) and ' + ' or '')..
  1100.       ((modStacks>0) and modStacks or '') )
  1101.   end
  1102.   print('Press ENTER')
  1103.  
  1104.   -- Wait while user press key
  1105.   read()
  1106.  
  1107.  
  1108.  
  1109.   -- ==============================
  1110.   -- Functions
  1111.   -- ==============================
  1112.  
  1113.   -- Compute slots pattern. Pattern shows what block index in whitch slot
  1114.   local slotsPattern = getSlotsPattern()
  1115.   local startPos = vector.new(currPos.x, currPos.y, currPos.z)
  1116.  
  1117.  
  1118.   -- Function same as GoTo, but consider position of building and incremental shifting
  1119.   local fillGoToFnc = function(x,y,z)
  1120.     -- Shift next coord with flags
  1121.     -- Userful for stairs and diagonals
  1122.     local shift = vector.new()
  1123.     if y then shift.x = y*(fillFlags['x++'] and 1 or (fillFlags['x--'] and -1 or 0)) end
  1124.     if x then shift.y = x*(fillFlags['y++'] and 1 or (fillFlags['y--'] and -1 or 0)) end
  1125.     if y then shift.z = y*(fillFlags['z++'] and 1 or (fillFlags['z--'] and -1 or 0)) end
  1126.    
  1127.     local changeVec = pos + shift    
  1128.    
  1129.     -- nil means we dont need change current position
  1130.     if not x then x = currPos.x-changeVec.x end
  1131.     if not y then y = currPos.y-changeVec.y end
  1132.     if not z then z = currPos.z-changeVec.z end
  1133.  
  1134.     local targetPos = vector.new(x,y,z) + changeVec
  1135.     turtleGoToP(targetPos)
  1136.   end
  1137.  
  1138.  
  1139.   -- If we handle some unsolutionabled error, we can hope only on user.
  1140.   -- Going to start and waiting until he fix all
  1141.   local backToStartFnc = function(msg)
  1142.     writeMessage(msg, messageLevel.ERROR)
  1143.    
  1144.     turtleGoTo(0,0,0)
  1145.     turtleSetOrientation(way.FORWARD)
  1146.    
  1147.     pressAnyKey()
  1148.   end
  1149.  
  1150.   -- Go to start and try reload while accomplished
  1151.   local reloadFnc = function(blockIndex)
  1152.  
  1153.     -- Up over structure if volume
  1154.     if(currPos.y ~= 0) then
  1155.       turtleGoTo(currPos.x, currPos.y, sizeZ+1)
  1156.     end
  1157.  
  1158.     local isReloaded = false
  1159.    
  1160.     while isReloaded==false do
  1161.       turtleGoTo(0, 0, 0)
  1162.       local reloadedPattern = reloadForFilling(slotsPattern, blacklistPattern)
  1163.      
  1164.       -- If some slots was not reloaded, leave them in blacklist
  1165.       for i=1, 16 do
  1166.         if(reloadedPattern[i] > 0) then
  1167.           blacklistPattern[i] = 0
  1168.         end
  1169.       end
  1170.      
  1171.       -- Check if we reloaded needed blockIndex
  1172.       if findInSlotsArrayByPattern(slotsPattern, blockIndex, blacklistPattern) == 0 then
  1173.         backToStartFnc('Error: Reloading failed. Please make storage and press any key')
  1174.       else
  1175.         isReloaded = true
  1176.       end
  1177.     end
  1178.   end
  1179.  
  1180.  
  1181.   -- The main function of placing blocks with parameters
  1182.   local fillFnc = function(x,y,z,direct,orient, blockIndex)
  1183.  
  1184.     -- Error text only for fatals, where program cant do nothing
  1185.     local fillError
  1186.    
  1187.     repeat -- Repeat until no fillErrors
  1188.       fillError = nil
  1189.      
  1190.       if( blockIndex ~= nil) then  
  1191.         if blockIndex > 0 then
  1192.           local slotWithNeededItem = findInSlotsArrayByPattern(slotsPattern, blockIndex, blacklistPattern)
  1193.           if(slotWithNeededItem ~= 0) then
  1194.             fillGoToFnc(x,y,z)
  1195.             if(orient)then turtleSetOrientation(orient) end -- Can be nil - orientation don't matter
  1196.            
  1197.             -- We have block and can put it on place
  1198.             placeBlock(slotWithNeededItem, direct)
  1199.            
  1200.             -- If slot was emptyed, we must note, that now there will be thrash
  1201.             -- Each next time when turtle dig, empty slot will filling
  1202.             if(turtle.getItemCount(slotWithNeededItem) == 0) then
  1203.               blacklistPattern[slotWithNeededItem] = 1
  1204.              
  1205.               -- Check again if we have another slot with item
  1206.               if( findInSlotsArrayByPattern(slotsPattern, blockIndex, blacklistPattern) == 0)then
  1207.                 -- No avaliable blocks to build!
  1208.                 -- Save coords, reload and return
  1209.                 local buildProgressStopPos = vector.new(currPos.x, currPos.y, currPos.z)
  1210.                 local stopOrient = currOrient
  1211.                
  1212.                 reloadFnc(blockIndex)
  1213.                
  1214.                 -- Go back to work
  1215.                 turtleGoTo(0, 0, 0)
  1216.                 turtleGoTo(0, 0, sizeZ+1)
  1217.                 turtleGoToP(buildProgressStopPos)
  1218.               end
  1219.             end
  1220.           else
  1221.             -- Fatal fillError. We are probably reloaded, but still havent blocks to place
  1222.             -- This can happend only with bug in code
  1223.             fillError = 'Fatal fillError: No blocks to place on {'..x..','..y..','..z..'}\nI dont know what went wrong.'
  1224.             backToStartFnc(fillError)
  1225.           end
  1226.         else -- blockIndexToPlace == 0
  1227.           fillGoToFnc(x,y,z)
  1228.           if(orient)then turtleSetOrientation(orient) end -- Can be nil - orientation don't matter
  1229.          
  1230.           -- Remove block here and do nothing
  1231.           turtleDig(direct)
  1232.         end
  1233.       else -- blockIndexToPlace == nil
  1234.        
  1235.       end
  1236.     until not fillError
  1237.    
  1238.     return nil
  1239.   end -- fillFnc()
  1240.  
  1241.  
  1242.   -- ==============================
  1243.   -- Iterators
  1244.   -- ==============================
  1245.  
  1246.  
  1247.   -- move to start position
  1248.   fillGoToFnc(0, 0, ((sizeZ>1) and 1 or 0))
  1249.  
  1250.   -- y-> is printing method, when we fill from us to forward
  1251.   if     fillFlags['y->'] then
  1252.     for _y=0, sizeY-1 do
  1253.       for _z=0, sizeZ-1 do
  1254.         for _x=0, sizeX-1 do
  1255.           local x,y,z = _x,_y,_z
  1256.           if(z%2==1) then x = sizeX-x-1 end -- Ping-pong
  1257.          
  1258.           fillFnc(x,y,z+1, way.DOWN, nil, vol[z][y][x])
  1259.         end
  1260.       end
  1261.     end
  1262.    
  1263.   -- Printer working as usual building programs
  1264.   elseif fillFlags['printer'] then
  1265.     for _z=0, sizeZ-1 do
  1266.       for _y=0, sizeY-1 do
  1267.         for _x=0, sizeX-1 do
  1268.           local x,y,z = _x,_y,_z
  1269.           if(z%2==1) then y = sizeY-y-1; x = sizeX-x-1 end -- Ping-pong
  1270.           if(y%2==1) then x = sizeX-x-1 end                -- Ping-pong
  1271.          
  1272.           fillFnc(x,y,z+1, way.DOWN, nil, vol[z][y][x])
  1273.         end
  1274.       end
  1275.     end
  1276.    
  1277.   -- And most awesome and fast filling method
  1278.   -- It filling 3 blocks per move
  1279.   else
  1280.     local zStepsCount    = math.ceil(sizeZ/3)-1 -- Count of levels, where robot moves horisontally
  1281.     local lastZStepIsCap = (sizeZ%3 == 1) -- The top level of volume is last level where turtle moves hor-ly
  1282.     local zLastStepLevel = zStepsCount*3+(lastZStepIsCap and 0 or 1) -- Z level where turtle will move last
  1283.    
  1284.     for _z=0, zStepsCount do
  1285.       for _y=0, sizeY-1 do
  1286.         for _x=0, sizeX-1 do
  1287.           local x,y = _x,_y
  1288.           x = sizeX - x - 1 -- Revert X coordinates. Filling will be from right to left
  1289.          
  1290.           local z = _z*3+1
  1291.           local currZStepIsLast = (_z==zStepsCount)
  1292.           if currZStepIsLast then z = zLastStepLevel end -- Cap of volume
  1293.          
  1294.           -- Ping-pong
  1295.           local currZIsEven = (_z%2==0)
  1296.           local horisontDirect = way.BACK -- Specific orientation, when we move to next Y pos
  1297.           local horisontShift  = -1       -- Y direction, when we move to next Y pos
  1298.           if not currZIsEven then
  1299.             y = sizeY - y - 1
  1300.             horisontDirect = way.FORWARD
  1301.             horisontShift = 1
  1302.           end          
  1303.          
  1304.           local escapeShaftHere = (x==0 and y==0)
  1305.           local hereWeWillGoUp = ((x==0 and ((_z%2==0 and y==sizeY-1) or (_z%2==1 and y==0))) and _z < zStepsCount)
  1306.          
  1307.  
  1308.           -- Fill down
  1309.           if z>0 and not (lastZStepIsCap and currZStepIsLast) and not escapeShaftHere then
  1310.             fillFnc(x,y,z, way.DOWN, nil, vol[z-1][y][x])
  1311.           end
  1312.          
  1313.           -- Fill forward
  1314.           if x < sizeX-1 then
  1315.             fillFnc(x,y,z, way.FORWARD, way.RIGHT, vol[z][y][x+1])
  1316.           end
  1317.          
  1318.           -- Fill back previous line when we starting new x line
  1319.           if not currZStepIsLast or (not currZIsEven and currZStepIsLast) then
  1320.             if x==0 and ((currZIsEven and y>0) or ((not currZIsEven) and y<sizeY-1)) and
  1321.              not (x==0 and y==1 and currZIsEven) then
  1322.               fillFnc(x,y,z, way.FORWARD, horisontDirect, vol[z][y+horisontShift][x])
  1323.             end
  1324.           end
  1325.          
  1326.           -- Fill UP
  1327.           if z<sizeZ-1 and not hereWeWillGoUp and (not escapeShaftHere or currZStepIsLast) then
  1328.             fillFnc(x,y,z, way.UP, nil, vol[z+1][y][x])
  1329.           end
  1330.          
  1331.           -- Go forward if we finished the line
  1332.           if x==0 and ((_z%2==0 and y<sizeY-1) or (_z%2==1 and y>0)) then
  1333.             turtleGoTo(currPos.x, currPos.y-horisontShift, currPos.z)
  1334.           end
  1335.          
  1336.           -- Move up and fill bocks down, if we advance to next Z level
  1337.           if hereWeWillGoUp then
  1338.             local nextZLevel = (_z+1)*3 + 1
  1339.             if lastZStepIsCap and (_z+1==zStepsCount) then nextZLevel = nextZLevel-1 end -- Cap of volume
  1340.             if(escapeShaftHere)then
  1341.               fillGoToFnc(nil, nil, nextZLevel)
  1342.             else
  1343.               for zAdvance=z+1, nextZLevel do
  1344.                 fillGoToFnc(x,y,zAdvance)
  1345.                 fillFnc(x,y,zAdvance, way.DOWN, nil, vol[zAdvance-1][y][x])
  1346.               end
  1347.             end
  1348.           end
  1349.          
  1350.         end
  1351.       end
  1352.     end
  1353.    
  1354.     -- We use our shaft to go back to x=0, y=0
  1355.     if not (zStepsCount%2==1) then
  1356.       for y=sizeY-2, 0, -1 do
  1357.         fillFnc(0, y, zLastStepLevel, way.FORWARD, way.FORWARD, vol[zLastStepLevel][y+1][0])
  1358.       end
  1359.     end
  1360.    
  1361.     -- And then go down to z 0
  1362.     for z=zLastStepLevel-1, 0, -1 do
  1363.       fillFnc(0, 0, z, way.UP, nil, vol[z+1][0][0])
  1364.     end
  1365.     fillGoToFnc(0,0,0)
  1366.    
  1367.     -- And last block
  1368.     fillFnc(0, -1, 0, way.FORWARD, way.FORWARD, vol[0][0][0])
  1369.   end
  1370.  
  1371.  
  1372.   -- ==============================
  1373.   -- Finishing
  1374.   -- ==============================
  1375.  
  1376.   -- Now we finished filling territory. Just go home
  1377.   if isGoBackAfterFill == true then
  1378.     turtleGoTo(startPos.x, startPos.y, startPos.z)
  1379.     turtleSetOrientation(way.FORWARD)
  1380.   end
  1381.  
  1382.   return true
  1383. end
  1384.  
  1385. -- ********************************************************************************** --
  1386. -- **                                                                              ** --
  1387. -- **                                                                              ** --
  1388. -- **                                                                              ** --
  1389. -- **                                                                              ** --
  1390. -- **                                                                              ** --
  1391. -- **                            Startup functions                                 ** --
  1392. -- **                                                                              ** --
  1393. -- **                                                                              ** --
  1394. -- **                                                                              ** --
  1395. -- **                                                                              ** --
  1396. -- **                                                                              ** --
  1397. -- ********************************************************************************** --
  1398. local args = { ... }
  1399.  
  1400. startupMode = {
  1401.   'Fill', 'Lake drying'
  1402. }
  1403.  
  1404.  
  1405. function init()
  1406.  
  1407.   -- add to patterns all .nfa files
  1408.   local allFiles = fs.list('')
  1409.   local only_nfa = {}
  1410.   for k,v in pairs(allFiles) do
  1411.     if(string.sub(v,#v-3,#v) == '.nfa')then
  1412.       fillPattern[v] = loadNFA(v)
  1413.     end
  1414.   end
  1415.  
  1416.  
  1417.   -- Detect whether this is a wireless turtle, and if so, open the modem
  1418.   local peripheralConnected = peripheral.getType("right")
  1419.   if (peripheralConnected == "modem") then
  1420.     isWirelessTurtle = true
  1421.   end
  1422.    
  1423.   -- If a wireless turtle, open the modem
  1424.   if (isWirelessTurtle == true) then
  1425.     turtleId = os.getComputerLabel()
  1426.     rednet.open("right")
  1427.   end
  1428.  
  1429.   clear()
  1430.  
  1431.   local welcomingText =
  1432. [[=======================================
  1433. == Krutoy Turtle - universal builder ==
  1434. =======================================
  1435. ]]
  1436.   while true do
  1437.     local paramsLine = welcomingText
  1438.     local separator = '----------------------\n'
  1439.     local result = 0
  1440.     local currLine = 'Select mode:\n'
  1441.     local n = 1
  1442.    
  1443.     for k,v in pairs(startupMode) do
  1444.       currLine = currLine..' '..n..' - '..v..'\n'
  1445.       n = n+1
  1446.     end
  1447.     result = readNumberParametr(paramsLine..currLine, 1, #startupMode)
  1448.     local mode = startupMode[result]
  1449.    
  1450.    
  1451.     if(mode == 'Lake drying') then
  1452.       while turtle.getItemCount(1) == 0 do
  1453.           clear()
  1454.           print('Place buket in first slot')
  1455.           sleep(1)
  1456.       end
  1457.      
  1458.       currLine = 'Specify size by x y z (z is deph), separate with spaces, and press ENTER:\n'
  1459.       result = readTableOfNumbers(currLine, false, 3, "%S+")
  1460.       local sizeX,sizeY,sizeZ = result[1],result[2] ,result[3]
  1461.      
  1462.      
  1463.       turtle.select(1)
  1464.       turtle.refuel()
  1465.       local startPos = vector.new(currPos.x,currPos.y,currPos.z)
  1466.       for z=0,sizeZ-1 do
  1467.         for x=0,sizeX-1 do
  1468.           for y=0,sizeY-1 do
  1469.             if(x%2==1) then y = sizeY - y - 1 end -- Ping-pong
  1470.             turtleGoTo(x,y+1,-z)
  1471.             turtle.placeDown()
  1472.             turtle.refuel()
  1473.            
  1474.             clear()
  1475.             print('Fuel level: '..turtle.getFuelLevel())
  1476.           end
  1477.         end
  1478.       end
  1479.       turtleGoTo(nil, nil, startPos.z)
  1480.       turtleGoToP(startPos)
  1481.       turtleSetOrientation(way.FORWARD)
  1482.     end
  1483.    
  1484.      
  1485.    
  1486.     if(mode == 'Fill') then
  1487.       local sizeX,sizeY,sizeZ
  1488.       local pattern = nil
  1489.       local pos = vector.new(0,1,0) -- Trutle build start is block forward of it
  1490.       local fillFlags = {}
  1491.      
  1492.       if not IDE then
  1493.         paramsLine = paramsLine..'MODE:    Fill\n'
  1494.         currLine = 'Select fill pattern:\n'
  1495.         n = 1
  1496.         for k,v in pairs(fillPattern) do
  1497.           currLine = currLine..' '..n..' - '..k..'\n'
  1498.           n = n+1
  1499.         end
  1500.         result = readNumberParametr(paramsLine..separator..currLine, 1, n)
  1501.         n = 1
  1502.         for k,v in pairs(fillPattern) do
  1503.           if(n == result) then
  1504.             pattern = k
  1505.             paramsLine = paramsLine..'PATTERN: '..pattern..'\n'
  1506.             break
  1507.           end
  1508.           n = n+1
  1509.         end
  1510.        
  1511.        
  1512.         currLine = 'Specify size by x y z, separate with spaces, and press ENTER:\n'
  1513.         result = readTableOfNumbers(paramsLine..separator..currLine, false, 3, "%S+")
  1514.         sizeX,sizeY,sizeZ = result[1],result[2],result[3]
  1515.         paramsLine = paramsLine..'SIZE:    {'..sizeX..', '..sizeY..', '..sizeZ..'}\n'
  1516.        
  1517.        
  1518.         currLine = 'Add flags if need, separate with commas, and press ENTER\n'
  1519.         result = readTable(paramsLine..separator..currLine, true, "%s*([^,]+)")
  1520.         if(result) then fillFlags = makeSet(result) end
  1521.       else
  1522.         sizeX,sizeY,sizeZ, pattern, pos, fillFlags =
  1523.             5, 5, 9,'BoxGrid', vector.new(), {}
  1524.       end
  1525.      
  1526.      
  1527.       ---------------------------------------
  1528.       fill(sizeX,sizeY,sizeZ, pattern, pos, true, fillFlags)
  1529.     end
  1530.   end
  1531. end
  1532.  
  1533.  
  1534. init()
RAW Paste Data