Bartouille

Lonesome BuilderCraft API (LBA) - 1.0b

Sep 26th, 2016
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 33.14 KB | None | 0 0
  1. --[[-------------------------------------------------------------------------
  2. LONESOME BUILDERCRAFT API (LBA) for Computer Craft Turtles
  3. @Author         Bart'Ouille
  4. @licence        GNU-GPL 3.0
  5.                 I'll appreciate if you keep credit me if you use or fork this api
  6. @Version        1.0b
  7. @Description    This API is a complete way to program turtles for building many shapes, including custom ones while automatically managing fuel and materials.
  8.                 It handles full control over turtle parameters, provides a complete error handler, a remote command mode and many other features
  9.                 Turtles are provided by Computercraft mod for minecraft (http://computercraft.info).
  10. @Website        http://www.liqueurdetoile.com/gaming/lba
  11. @Channel        https://www.youtube.com/channel/UCUavPLdEJR3CL5mIUrSmpXw
  12. ---------------------------------------------------------------------------]]
  13.  
  14. -- Construction functions
  15. -- function dot(x, y, z, m)
  16. -- function line(x1, y1, z1, x2, y2, z2, m)
  17. -- function rectangleY (x1, z1, x2, z2, y, m, filled, thickness)
  18. -- function xmobFloor(x1, z1, x2, z2, y, m)
  19. -----------------------------------------------------------------------------
  20. -- YOUR CODE HERE
  21. -- Faster than scrolling to the end :)
  22. -----------------------------------------------------------------------------
  23. function lba_yourBuild()
  24.     -- Xmob Tower Script with 5 spawning floors
  25.     local xStart = 2
  26.     local yStart = -4  
  27.     local zStart = 0
  28.    
  29.    
  30.     -- Pilar for climbing
  31.     dot(xStart,yStart,zStart-1, "stone@0")
  32.     -- Initial area for building
  33.     rectangleY (xStart,zStart,xStart+26,zStart+26,yStart,"stone@0", true)
  34.     -- Crashing floor
  35.     rectangleY (xStart,zStart,xStart+26,zStart+26,yStart+1,"stone_slab@0", true)
  36.     -- Pilar for climbing
  37.     for i=1,26 do dot(xStart,yStart+i,zStart-1, "stone@0") end
  38.     -- Pilar + walls for masking light on spawn floors
  39.     for i=27,41 do
  40.         dot(xStart,yStart+i,zStart-1, "stone@0")
  41.         rectangleY(xStart+2,zStart+2,xStart+24,zStart+24,yStart+i,"stone@0",false,1)
  42.     end
  43.     -- Spawning plaforms, surrounded by walls and a 2 blocks path for player moving
  44.     for i=0,4 do
  45.         dot(xStart,yStart+42+3*i,zStart-1, "stone@0")
  46.         rectangleY(xStart,zStart,xStart+26,zStart+26,yStart+42+3*i,"stone_slab@0", false, 2)
  47.         rectangleY(xStart+2,zStart+2,xStart+24,zStart+24,yStart+42+3*i,"stone@0", false, 1)
  48.         xmobFloor(xStart+3,zStart+3,xStart+23,zStart+23,yStart+42+3*i,"stone@0", false, 1)
  49.         dot(xStart,yStart+43+3*i,zStart-1, "stone@0")
  50.         rectangleY(xStart+2,zStart+2,xStart+24,zStart+24,yStart+43+3*i,"stone@0", false, 1)
  51.         dot(xStart,yStart+44+3*i,zStart-1, "stone@0")
  52.         rectangleY(xStart+2,zStart+2,xStart+24,zStart+24,yStart+44+3*i,"stone@0", false, 1)
  53.     end
  54.     -- No roof for prevent spawning while finishing tower equipment
  55. end
  56.  
  57. -----------------------------------------------------------------------------
  58. -- BASIC OPTIONS
  59. -----------------------------------------------------------------------------
  60. -- All positions are stored using the vector feature
  61. -- CARE : As in game, y axis is the height
  62. -- You can acces x, y and z coordinates by calling vectorName.x, vectorName.y, vectorName.z
  63.  
  64. -- Method to compute position in space
  65. -- Set this to true for GPS location value
  66. -- Set this to false for self relative values
  67. initPositionByGPS = false
  68. startPosition = 0
  69.  
  70. -- Set the turtle for autodigging or autoattack when moving
  71. autoDig = true          -- Care with this one if you don't build from bottom to top layers
  72. autoAttack = true
  73. maxTries = 3            -- Number of attempts to dig/attack to be made if stuck while moving
  74.  
  75. -----------------------------------------------------------------------------
  76. -- AUTOREFUEL FEATURES
  77. -- Autorefuel lets the turtle going for refuel by itsel as needed
  78. -- In order to work, one slot must be kept free
  79. -----------------------------------------------------------------------------
  80. -- Set autoRefuel to false for disabling this feature
  81. autoRefuelEnabled = true
  82.  
  83. -- Turtle position to go when refueling
  84. -- DO NOT PUT FUEL POSITION BUT TURTLE POSITION (just above for instance)
  85. fuelPosition = vector.new(0,0,0)
  86.  
  87. -- Indicates in which inner slot the turtle must seek fuel (1-16)
  88. fuelSlot = 1
  89. -- Indicates which direction the turtle must facing to access fuel chest (suck) and, optionally, garbage chest (for dropping buckets)
  90. -- With GPS location, direction are 0 for East, 90 for North, 180 for West and 270 for South
  91. -- With relative coordinates, the direction 0 is the one that the turtle is facing when places in the world. Next values can be found by adding 90 while rotating left hand. If the turtle is facing East when placed, values will be the same than GPS location
  92. -- Up direction's value is 1 and Down direction's value is -1
  93. -- If not set, it will throw an error when using autoRefuel feature
  94. autoRefuelSuckDirection = -1
  95. autoRefuelDropDirection = 180
  96.  
  97. -----------------------------------------------------------------------------
  98. -- AUTOREFILL MATERIALS FEATURES
  99. -- Autorefill lets the turtle fetching materials by itself as needed
  100. -- CAUTION : If used with autorefuel feature, the fuel slot will be locked
  101. -----------------------------------------------------------------------------
  102. -- Set autoRefill to false for disabling this feature
  103. autoRefillEnabled = true
  104.  
  105. -- You can provide materials location in two ways
  106. materialLocation = {}
  107. registeredMaterials = 0
  108.  
  109. -- HINT : LOCKING MATERIALS FOR SLOTS
  110. -- If you want to make your turtle to always keep the same mix of materials in its inventory, simply fill these slots with at least one block when starting script. The turtle will scan its inventory at startup and keep this mix all the way
  111. -- If you choose to leave the turtle inventory clear at startup, it will fill it with choosen block at each construction step then unloading and go for next block in case of changing
  112. -- CARE : If slots are not locked, you can't use a single container for multiple blocks because turtle will only suck the first available stack
  113.    
  114. -- Set it to false if you plan to use hard coding way (at yout own risk)
  115. autoDetectMaterials = true
  116. -- HINT : For avoidind turtle destroying your containers, set a startRange and a endRange with turtle's basic movement rule (if going down, movement is on x axis, then z axis and finally y axis - If going up, movement is on y axis, then x axis anf finally z axis)
  117. -- HINT : When refilling materials, turtle will always go first to startRange position, then to chest and leave by going to endRange position
  118. -- HINT : Better to be a line and you can put many chests to each position
  119. autoDetectStartPosition = vector.new(0,0,-2)        -- Set turtle position start for scanning container's area
  120. autoDetectEndPosition = vector.new(0,0,-2)          -- Set turtle position end for scanning container's area
  121.  
  122. -----------------------------------------------------------------------------
  123. -- REDNET FEATURES
  124. -- Commit turtle messages through rednet
  125. -----------------------------------------------------------------------------      
  126. -- COMING SOON !
  127.  
  128. -----------------------------------------------------------------------------      
  129. -- GLOBAL VARIABLES FOR STATES AND STATISTICS
  130. -----------------------------------------------------------------------------
  131. -- States
  132. turtleStates = {
  133.     isOnInit = false,               -- State when initializing
  134.     isScanningMaterialArea = false, -- State when scanning material area
  135.     isGoingForFuel = false,         -- State when fetching fuel
  136.     isGoingForMaterials = false,    -- State when fetching materials
  137.     isBuilding = false,             -- State when building
  138.     isFuelShortage = true,          -- State when running out of fuel
  139.     isMaterialShortage = true,      -- State when running out of materials
  140.     isOnError = false,              -- State when on error
  141.     isStuck = false                 -- State when stuck in a place
  142. }
  143.  
  144. -- Log level for verbose (cumulative)
  145. -- 0 : nothing, 1 : errors, 2 : warnings, 3 : informations, 4 : all sides messages
  146. logTermLevel = 3        -- Log level for turtle terminal messages
  147. logRednetLevel = 0      -- Log level for rednet broadcast message
  148.  
  149. -- Statistics
  150. startTime = os.time()
  151. totalBlocks = 0
  152.  
  153. -----------------------------------------------------------------------------
  154. -- INITIALIZATION AND I/O FUNCTIONS
  155. -----------------------------------------------------------------------------
  156. -- @function    lba_initialize      Mandatory. Launch all subroutines
  157. -- @function    lba_commandMode     Enter remote command mode
  158. -- @function    lba_getPosition     returns and optionnally display turtle position
  159. -- @function    lba_log         generic wrapper for local and rednet display
  160.  
  161. -- Performs all initializations requests and settings
  162. -- MUST BE LAUNCH EACH TIME
  163. local function lba_initialize()
  164.     turtleStates.isOnInit = true
  165.     lba_log("Lonesome buildercraft init",3)
  166.    
  167.     -- Coordinates system
  168.     lba_log("Setting coordinates system",3)
  169.     if initPositionByGPS then
  170.         lba_log("Looking for GPS signal...",4)
  171.         local x, y, z = gps.locate()
  172.         if x then
  173.             lba_log("GPS found. Starting calibration",4)
  174.             turtlePosition = vector.new(x,y,z)
  175.             startPosition = turtlePosition
  176.             forward()
  177.             local x, y, z = gps.locate()
  178.             if (turtlePosition.x - x) == 0 then
  179.                 if (turtlePosition.z - z) == 1 then
  180.                     turtleDirection = 90                -- z decreasing - Facing North
  181.                 else
  182.                     turtleDirection = 270               -- z increasing - Facing South
  183.                 end
  184.             else
  185.                 if (turtlePosition.x - x) == 1 then
  186.                     turtleDirection = 180               -- x decreasing - Facing West
  187.                 else
  188.                     turtleDirection = 0                 -- x increasing - Facing East
  189.                 end
  190.             end
  191.             backward()
  192.             faceTo(0)
  193.             lba_log("Calibration finished",4)
  194.         else
  195.             turtlePosition = vector.new(0,0,0)
  196.             startPosition = turtlePosition
  197.             turtleDirection = 0
  198.             lba_log("No GPS system found. Falling back to relative coordinates system",2)
  199.             lba_log("The turtle is at x=0, z=0, y=0 and facing direction 0",4)
  200.             lba_log("It should be EAST ingame for matching x and z game axis",4)
  201.             lba_log("X are increasing in front of turtle and Z are increasing on right of the turtle",4)
  202.         end
  203.     else
  204.         turtlePosition = vector.new(0,0,0)
  205.         startPosition = turtlePosition
  206.         turtleDirection = 0
  207.         lba_log("Relative coordinates are used",3)
  208.         lba_log("The turtle is at x=0, z=0, y=0 and facing direction 0",4)
  209.         lba_log("It should be matching EAST ingame for matching x and z game axis",4)
  210.         lba_log("X are increasing in front of turtle and Z are increasing on right of the turtle",4)
  211.     end
  212.    
  213.     -- Tests if turtle is equipped with a pickaxe for autodig and autoattack features
  214.     -- COMING SOON
  215.    
  216.     -- Fuel System Initialization
  217.     lba_log("Fuel System initialization",3)
  218.     if autoRefuelEnabled then
  219.         lba_log("Refuel : Auto",3)
  220.         lba_log("Checking distance to Fuel supply",4)
  221.         if not(checkIfRefuelNeeded()) then
  222.             lba_log("Enough fuel to start work",3)
  223.         else
  224.             waitForRefuel()
  225.         end        
  226.     else
  227.         lba_log("Refuel : Manual. Don't forget me !",3)
  228.     end
  229.    
  230.     -- Materials initialization
  231.     lba_log("Materials management initialization",3)
  232.     -- Checks inventory for locked slots
  233.     local lockedSlots = false
  234.     for i=1,16 do
  235.         if (i ~= fuelSlot) then
  236.             local m = lba_getSlotContent(i)
  237.             if m then
  238.                 if not(materialLocation[m]) then materialLocation[m] = {} end
  239.                 if not(materialLocation[m].locked) then materialLocation[m].locked = {i}
  240.                     else table.insert(materialLocation[m].locked, i)
  241.                 end
  242.                 lockedSlots = true
  243.             end
  244.         end        
  245.     end
  246.    
  247.     if lockedSlots then
  248.         lba_log("Locked slots Enabled",3)
  249.     else
  250.         lba_log("Locked slots disabled",3)
  251.     end
  252.    
  253.     if autoDetectMaterials then
  254.         scanMaterialsArea()
  255.         lba_log("Materials area scan complete",3)
  256.         lba_log(registeredMaterials.." different materials registered",3)
  257.     else
  258.         lba_log("Automatic materials area detection disabled")
  259.     end
  260.        
  261.     lba_log("Initialization complete\n",3)
  262.     turtleStates.isOnInit = false
  263. end
  264.  
  265. function lba_end()
  266.     goTo(0,0,0)
  267.     faceTo(0)
  268.     local endTime = os.time()
  269.     local elapsed = math.floor((endTime - startTime) * 50)
  270.     local hours = math.floor(elapsed/3600)
  271.     local minutes = math.floor((elapsed/60)%60)
  272.     local seconds = math.floor(elapsed%60%3600)
  273.     lba_log("Job's done!",3)
  274.     lba_log("Elapsed time : "..hours.."h"..minutes.."m"..seconds.."s",3)
  275.     lba_log("Blocks used : "..totalBlocks,3)
  276. end
  277.  
  278. function lba_commandMode()
  279.     -- TODO COMING SOON
  280. end
  281.  
  282. function lba_getPosition(verbose)
  283. -- @params  verbose     (optional) If true, will display the position
  284.     verbose = verbose or true
  285.     if verbose then
  286.         lba_log("x : "..turtlePosition.x.." - y : "..turtlePosition.y.." - z : "..turtlePosition.z.." - o : "..turtleDirection, 3);
  287.     end
  288.     return turtlePosition
  289. end
  290.  
  291. function lba_log(message, level, delay)
  292. --@params   message     String      Message to display
  293. --          level       Number      LogLevel for the message (see parameters section)
  294. --          delay       Number      Time to wait after display in seconds
  295.     level = level or 4
  296.     delay = delay or (4-level)*0.33
  297.     local levelMessage = ""
  298.    
  299.     -- Manage turtle term display
  300.     if(level <= logTermLevel) then
  301.         if level == 1 then
  302.             levelMessage = "!ERR : "
  303.         elseif level == 2 then
  304.             levelMessage = "Warn : "
  305.         elseif level == 3 then
  306.             levelMessage = "Info : "
  307.         else
  308.             levelMessage = "Verb : "
  309.         end    
  310.        
  311.         -- Formatting message based on screen size
  312.         local w, h = term.getSize()
  313.         local maxLen = w - string.len(levelMessage)
  314.         local i = 0
  315.         local line = ""
  316.        
  317.         for w in string.gmatch(message, "[%w%p]+%s?") do
  318.             if (i + string.len(w)) > maxLen then
  319.                 print(levelMessage,line)
  320.                 line = ""
  321.                 i = 0
  322.                 levelMessage = "       "
  323.             end
  324.             line = line..w
  325.             i = i + string.len(w)
  326.         end
  327.         print(levelMessage,line)       
  328.         sleep(delay)
  329.     end
  330.    
  331.     -- Manage rednet broadcast messages
  332.     -- TODO
  333. end
  334.  
  335. function lba_getSlotContent(slotNumber)
  336. --@input    slot    Number      Slot to be examined
  337. --@return           String      ItemName@damageValue, false if slot empty
  338.     local m = turtle.getItemDetail(slotNumber)
  339.     local ret = false
  340.     if m then
  341.         ret = string.match(m.name,"minecraft:(.+)")
  342.         ret = ret.."@"
  343.         ret = ret..m.damage    
  344.     end
  345.     return ret
  346. end
  347.  
  348. -----------------------------------------------------------------------------
  349. -- MOVEMENT AND ORIENTATION FUNCTIONS
  350. -----------------------------------------------------------------------------
  351. -- @function    left                turn turtle left
  352. -- @function    right               turn turtle right
  353. -- @function    faceTo              change turtle orientation to the provided angle
  354. -- @function    forward             move turtle forward and update its position
  355. -- @function    up                  move turtle up and update its position
  356. -- @function    down                move turtle down and update its position
  357. -- @function    goTo                move turtle to given coordinates
  358.  
  359. function left()
  360. --@ return  true
  361.     if turtle.turnLeft() then
  362.         turtleDirection = turtleDirection + 90
  363.         if turtleDirection == 360 then
  364.             turtleDirection = 0
  365.         end
  366.     end
  367.     return true
  368.  end
  369.  
  370. function right()
  371. --@ return  true
  372.     if turtle.turnRight() then
  373.         turtleDirection = turtleDirection - 90
  374.         if turtleDirection == -90 then
  375.             turtleDirection = 270
  376.         end
  377.     end
  378.     return true
  379. end
  380.  
  381. function faceTo(angle)
  382. --@params   angle   angle choosen between 0, 90, 180, 270
  383. --@ return  true
  384.     if angle ~= turtleDirection then    
  385.         local mod = (angle-turtleDirection)%360
  386.         if mod == 180 then
  387.             left()
  388.             left()
  389.         elseif mod == 90 then
  390.             left()
  391.         elseif mod == 270 then
  392.             right()
  393.         end
  394.     end
  395.     return true
  396. end
  397.  
  398. function forward(n)
  399. -- @params  n       (optional) Number of blocks to go
  400. -- @return  true    turtle moved all the way
  401. --          false   turtle didn't move all the way
  402.     n = n or 1
  403.    
  404.     for i=1,n do
  405.         if (turtleStates.isGoingForFuel == false) and autoRefuelEnabled then
  406.             checkIfRefuelNeeded()
  407.         end
  408.        
  409.         if turtle.getFuelLevel() == 0 then
  410.             waitForRefuel()
  411.         end
  412.    
  413.         local xi, zi = 0
  414.         local moved = false
  415.         local tries = 1
  416.         while (not moved) and (tries <= maxTries) do
  417.             if turtle.forward() then
  418.                 moved = true
  419.             else
  420.                 if autoDig then turtle.dig() end
  421.                 if autoAttack then turtle.attack() end
  422.                 if turtle.forward() then
  423.                     moved = true
  424.                 else
  425.                     tries = tries + 1
  426.                     if(tries <= maxTries) then
  427.                         lba_log("Failed to move forward. Trying again", 2)
  428.                     else
  429.                         lba_log("Error moving forward. Entering idle mode", 1)
  430.                         turtleStates['isOnError'] = true
  431.                         turtleStates['isStuck'] = true
  432.                     end
  433.                 end
  434.             end
  435.         end
  436.        
  437.         if moved then
  438.             if turtleDirection == 0 then
  439.                 xi = 1
  440.                 zi = 0
  441.             elseif turtleDirection == 90 then
  442.                 xi = 0
  443.                 zi = -1
  444.             elseif turtleDirection == 180 then
  445.                 xi = -1
  446.                 zi = 0
  447.             elseif turtleDirection == 270 then
  448.                 xi = 0
  449.                 zi = 1
  450.             end
  451.             local move = vector.new(xi, 0, zi)
  452.             turtlePosition = turtlePosition + move         
  453.         else
  454.             return false
  455.         end
  456.     end
  457.     return true
  458. end
  459.  
  460. function up(n)
  461. -- @params  n       Number of blocks to go
  462. -- @return  true    Turtle moved up
  463. --          false   Turtle didn't move
  464.     n = n or 1
  465.    
  466.     for i=1,n do
  467.         if (turtleStates.isGoingForFuel == false) and autoRefuelEnabled then
  468.             checkIfRefuelNeeded()
  469.         end
  470.        
  471.         if turtle.getFuelLevel() == 0 then
  472.             waitForRefuel()
  473.         end
  474.        
  475.         local moved = false
  476.         local tries = 1
  477.         while (not moved) and (tries <= maxTries) do
  478.             if turtle.up() then
  479.                 moved = true
  480.             else
  481.                 if autoDig then turtle.digUp() end
  482.                 if autoAttack then turtle.attackUp() end
  483.                 if turtle.up() then
  484.                     moved = true
  485.                 else
  486.                     tries = tries + 1
  487.                     if(tries < maxTries) then
  488.                         lba_log("Failed to move up. Trying again", 2)
  489.                     else
  490.                         lba_log("Error moving up. Entering idle mode", 1)
  491.                         turtleStates['isOnError'] = true
  492.                         turtleStates['isStuck'] = true
  493.                     end
  494.                 end
  495.             end
  496.         end
  497.        
  498.         if moved then
  499.             turtlePosition.y = turtlePosition.y + 1        
  500.         else
  501.             return false
  502.         end
  503.     end
  504.     return true
  505. end
  506.  
  507. function down(n)
  508. -- @params  n       Number of blocks to go
  509. -- @return  true    Turtle moved up
  510. --          false   Turtle didn't move
  511.     n = n or 1
  512.    
  513.     for i=1,n do
  514.         if (turtleStates.isGoingForFuel == false) and autoRefuelEnabled then
  515.             checkIfRefuelNeeded()
  516.         end
  517.        
  518.         if turtle.getFuelLevel() == 0 then
  519.             waitForRefuel()
  520.         end
  521.        
  522.         local moved = false
  523.         local tries = 1
  524.         while (not moved) and (tries <= maxTries) do
  525.             if turtle.down() then
  526.                 moved = true
  527.             else
  528.                 if autoDig then turtle.digDown() end
  529.                 if autoAttack then turtle.attackDown() end
  530.                 if turtle.down() then
  531.                     moved = true
  532.                 else
  533.                     tries = tries + 1
  534.                     if(tries < maxTries) then
  535.                         lba_log("Failed to move down. Trying again", 2)
  536.                     else
  537.                         lba_log("Error moving down. Entering idle mode", 1)
  538.                         turtleStates['isOnError'] = true
  539.                         turtleStates['isStuck'] = true
  540.                     end
  541.                 end
  542.             end
  543.         end
  544.        
  545.         if moved then
  546.             turtlePosition.y = turtlePosition.y - 1
  547.         else
  548.             return false
  549.         end
  550.     end
  551.     return true
  552. end
  553.  
  554. function goTo(x, y, z)
  555. -- Generic function for moving to a distant position
  556.     local xi = x - turtlePosition.x
  557.     local yi = y - turtlePosition.y
  558.     local zi = z - turtlePosition.z
  559.  
  560.     local function moveX(xi)
  561.         if xi > 0 then
  562.             faceTo(0)
  563.         elseif xi < 0 then
  564.             faceTo(180)
  565.         end
  566.         forward(math.abs(xi))
  567.     end
  568.  
  569.     local function moveZ(zi)
  570.         if zi > 0 then
  571.             faceTo(270)
  572.         elseif zi < 0 then
  573.             faceTo(90)
  574.         end
  575.         forward(math.abs(zi))
  576.     end
  577.    
  578.     if yi > 0 then
  579.         up(yi)
  580.         moveX(xi)
  581.         moveZ(zi)
  582.     else
  583.         moveX(xi)
  584.         moveZ(zi)
  585.         down(-yi)
  586.     end
  587. end
  588.  
  589. -----------------------------------------------------------------------------
  590. -- FUEL RELATED FUNCTIONS
  591. -----------------------------------------------------------------------------
  592. --@Function waitForRefuel       Enters turtle in error mode til refueling
  593. --@function distanceToFuel      Returns distance (in blocks) to fuel supply and triggers autoRefuel if set
  594.  
  595. function waitForRefuel()
  596. --@return   Boolean     Wait for user provide some fuel
  597.     turtleStates.isFuelShortage = true
  598.     turtleStates.isOnError = true
  599.     lba_log("I'm in error. Please provide some fuel in slot "..fuelSlot,1)
  600.     turtle.select(fuelSlot)
  601.     while true do
  602.         local event = os.pullEvent("turtle_inventory")
  603.         if turtle.refuel() then
  604.             lba_log("Refueled. Going back to work",3)
  605.             turtleStates.isFuelShortage = false
  606.             turtleStates.isOnError = false
  607.             break
  608.         else
  609.             lba_log("My inventory changed but I can't find any fuel in slot "..fuelSlot,2);
  610.         end    
  611.     end
  612. end
  613.  
  614. function distanceToFuel()
  615. --@return   Number      Distance to fuel supply
  616.     local vf = vector.new(0,0,0)
  617.     local distance = 0
  618.    
  619.     if turtleStates.isScanningMaterialArea or turtleStates.isGoingForMaterials then
  620.         -- Restricted cases, turtle must exit area by the start point, then going to start position before going for fuel for hoping to avoid containers
  621.         -- Therefore, distance is higher ^^
  622.         vf = autoDetectStartPosition - turtlePosition
  623.         distance = math.abs(vf.x) + math.abs(vf.y) + math.abs(vf.z)
  624.         vf = vf + startPosition - autoDetectStartPosition
  625.         distance = distance + math.abs(vf.x) + math.abs(vf.y) + math.abs(vf.z)
  626.         vf = vf + fuelPosition - startPosition
  627.         distance = distance + math.abs(vf.x) + math.abs(vf.y) + math.abs(vf.z)
  628.     else
  629.         vf = fuelPosition - turtlePosition     
  630.         distance = math.abs(vf.x) + math.abs(vf.y) + math.abs(vf.z)
  631.     end
  632.     return distance
  633. end
  634.  
  635. function checkIfRefuelNeeded()
  636. --@return   Boolean     True if fuel needed, false if not
  637.     local distance = distanceToFuel() + 1
  638.    
  639.     if turtle.getFuelLevel() <= distance then
  640.         if autoRefuelEnabled then
  641.             goRefuel()
  642.             return false
  643.         else
  644.             waitForRefuel()
  645.             return true
  646.         end
  647.     end
  648. end
  649.  
  650. function goRefuel()
  651. --@return   Number      Fuel Level
  652.     lba_log("I'm leaving work for refueling",3)
  653.     turtleStates.isGoingForFuel = true
  654.    
  655.     --Sauvegarde de la position
  656.     local xs = turtlePosition.x
  657.     local ys = turtlePosition.y
  658.     local zs = turtlePosition.z
  659.    
  660.     --Fuel Slot cleaning in case of previous mining/digging
  661.     turtle.select(fuelSlot)
  662.     if turtle.getItemCount(fuelSlot) > 0 then turtle.dropDown() end    
  663.    
  664.     goTo(fuelPosition.x, fuelPosition.y, fuelPosition.z)
  665.    
  666.     -- Refueling
  667.     while(turtle.getFuelLevel() < turtle.getFuelLimit()) do
  668.         -- Orients turtle to fuel storage
  669.         if math.abs(autoRefuelSuckDirection) > 1 then
  670.             faceTo(autoRefuelSuckDirection)
  671.             turtle.suck(1)
  672.         elseif autoRefuelSuckDirection == 1 then
  673.             turtle.suckUp(1)
  674.         else
  675.             turtle.suckDown(1)
  676.         end
  677.        
  678.         if not(turtle.refuel()) then
  679.             lba_log("Sorry. Can't refuel, please check fuel storage and refuel me in manual mode",1)
  680.             waitForRefuel()
  681.         end
  682.        
  683.         lba_log("Refueling "..turtle.getFuelLevel().."/"..turtle.getFuelLimit(),4)
  684.        
  685.         if turtle.getItemDetail() then
  686.             lba_log("Throwing garbage",4)
  687.             if math.abs(autoRefuelDropDirection) > 1 then
  688.                 faceTo(autoRefuelDropDirection)
  689.                 turtle.drop(1)
  690.             elseif autoRefuelDropDirection == 1 then
  691.                 turtle.dropUp(1)
  692.             else
  693.                 turtle.dropDown(1)
  694.             end        
  695.         end
  696.     end
  697.     lba_log("Refueled! Going back to work",3)
  698.     turtleStates.isGoingForFuel = false
  699.     goTo(xs, ys, zs)
  700. end
  701.  
  702. -----------------------------------------------------------------------------
  703. -- MATERIALS RELATED FUNCTIONS
  704. -----------------------------------------------------------------------------
  705. function waitForMaterials(material)
  706. --@param    material    String      Material needed
  707. --@return               Boolean     Wait for user provide some materials
  708.     turtleStates.isMaterialShortage = true
  709.     turtleStates.isOnError = true
  710.     lba_log("In on error. Please provide me "..material.." to build more",1)
  711.     local waiting = true
  712.    
  713.     while waiting do
  714.         local event, p1 = os.pullEvent("turtle_inventory")
  715.         for i=1,16 do
  716.             local m = lba_getSlotContent(i)
  717.             if m then
  718.                 if m == material then
  719.                     lba_log("Refilled "..material..". Going back to work",3)
  720.                     turtleStates.isMaterialShortage = false
  721.                     turtleStates.isOnError = false
  722.                     waiting = false
  723.                 else
  724.                     lba_log("My inventory changed but I can't find "..material.." in any slot",2);
  725.                 end
  726.             end
  727.         end    
  728.     end
  729. end
  730.  
  731. function scanMaterialsArea()
  732. --@return   nil
  733.     -- Looking for the turtle direction for optimizing detection
  734.     local scanOrder
  735.     local way = vector.new(0,0,0)
  736.     local wayToGo = vector.new(0,0,0)
  737.     local xn = 0
  738.     local yn = 0
  739.     local zn = 0
  740.    
  741.     way = autoDetectEndPosition - autoDetectStartPosition
  742.     if not(way.x == 0) then -- Scanning top, bottom, zleft, zright
  743.         scanOrder = {1, -1, 90, 270}
  744.         xn = (autoDetectEndPosition.x - autoDetectStartPosition.x)/math.abs(autoDetectEndPosition.x - autoDetectStartPosition.x)
  745.     elseif not(way.z == 0) then -- Scanning top, bottom, xleft, xright
  746.         scanOrder = {1, -1, 0, 180}
  747.         zn = (autoDetectEndPosition.z - autoDetectStartPosition.z)/math.abs(autoDetectEndPosition.z - autoDetectStartPosition.z)
  748.     elseif not(way.y == 0) then -- Scanning xleft, xright, zleft, zright
  749.         scanOrder = {0, 90, 180, 270}
  750.         yn = (autoDetectEndPosition.y - autoDetectStartPosition.y)/math.abs(autoDetectEndPosition.y - autoDetectStartPosition.y)
  751.     elseif (way.x == 0) and (way.y == 0) and (way.z == 0) then -- One single position for storage area
  752.         scanOrder = {1, -1, 0, 90, 180, 270}
  753.     else
  754.         lba_log("Unable to find my way in the storage area. Did you really set a straight line ?",1)
  755.         return false
  756.     end
  757.    
  758.     -- Starting autoDetection
  759.     turtleStates.isScanningMaterialArea = true
  760.     goTo(autoDetectStartPosition.x, autoDetectStartPosition.y, autoDetectStartPosition.z)
  761.     repeat
  762.         wayToGo = autoDetectEndPosition - turtlePosition
  763.         for k, d in pairs(scanOrder) do
  764.             doScanContainer(d)
  765.         end
  766.         goTo(turtlePosition.x + xn, turtlePosition.y + yn, turtlePosition.z + zn)
  767.     until wayToGo:length() == 0
  768.     turtleStates.isScanningMaterialArea = false
  769.     return true
  770. end
  771.  
  772. function doScanContainer(direction)
  773. --@params   direction   Number  Direction to do Scan
  774. --@return   nil
  775.     local function addItemToMaterialList(direction)
  776.         local m = lba_getSlotContent(fuelSlot)
  777.         lba_log("Found "..m.." at "..direction,4)
  778.         registeredMaterials = registeredMaterials+1
  779.         if(materialLocation[m]) then
  780.             materialLocation[m].x = turtlePosition.x
  781.             materialLocation[m].y = turtlePosition.y
  782.             materialLocation[m].z = turtlePosition.z
  783.             materialLocation[m].d = direction
  784.             if(materialLocation[m].locked) then -- Remplissage des solts réservés à ce matériel
  785.                 lba_log("Found locked slot(s) for "..m, 4)
  786.                 for i, slot in ipairs(materialLocation[m].locked) do fillSlot(m, slot) end                 
  787.                 turtle.select(fuelSlot)
  788.             end
  789.         else
  790.             materialLocation[m] = {x = turtlePosition.x, y = turtlePosition.y, z = turtlePosition.z, d = direction}    
  791.         end    
  792.     end
  793.    
  794.     lba_log("Starting location scan at "..direction,4)
  795.     turtle.select(fuelSlot)
  796.     if direction == 1 then
  797.         if turtle.suckUp(1) then
  798.             addItemToMaterialList(1)
  799.             turtle.dropUp()
  800.         end
  801.     elseif direction == -1 then
  802.         if turtle.suckDown(1) then
  803.             addItemToMaterialList(-1)
  804.             turtle.dropDown()
  805.         end
  806.     else
  807.         faceTo(direction)
  808.         if turtle.suck(1) then
  809.             addItemToMaterialList(direction)
  810.             turtle.drop()
  811.         end
  812.     end    
  813. end
  814.  
  815. function fillSlot(m, slot)
  816.     local ret = false
  817.    
  818.     lba_log("Filling slot "..slot.." with "..m,4)
  819.     turtle.select(slot)
  820.     local toSuck = 64 - turtle.getItemCount()
  821.     if materialLocation[m].d == 1 then
  822.         ret = turtle.suckUp(toSuck)    
  823.     elseif materialLocation[m].d == -1 then
  824.         ret = turtle.suckDown(toSuck)
  825.     else
  826.         faceTo(materialLocation[m].d)
  827.         ret = turtle.suck(toSuck)
  828.     end
  829.     return ret
  830. end
  831.  
  832. function emptySlot(m, slot)
  833.     local ret = false
  834.    
  835.     lba_log("Emptying slot "..slot.." containing "..m,4)
  836.     turtle.select(slot)
  837.     local toDrop = turtle.getItemCount()
  838.     if materialLocation[m].d == 1 then
  839.         ret = turtle.dropUp(toDrop)    
  840.     elseif materialLocation[m].d == -1 then
  841.         ret = turtle.dropDown(toDrop)
  842.     else
  843.         faceTo(materialLocation[m].d)
  844.         ret = turtle.drop(toDrop)
  845.     end
  846.     return ret
  847. end
  848.  
  849. function goRefill(m)
  850. --@params       m       string      material to fetch
  851.     --Position record
  852.     local xs = turtlePosition.x
  853.     local ys = turtlePosition.y
  854.     local zs = turtlePosition.z
  855.     local shipped = false
  856.    
  857.     lba_log("I'm leaving work for refilling "..m, 3)
  858.     turtleStates.isGoingForMaterials = true
  859.    
  860.     goTo(autoDetectStartPosition.x, autoDetectStartPosition.y, autoDetectStartPosition.z)
  861.    
  862.     if not(materialLocation[m].locked) then
  863.         -- Emptying inventory first when not using locked slots
  864.         for i = 1, 16 do
  865.             if i~=fuelSlot then
  866.                 turtle.select(i)
  867.                 cm = lba_getSlotContent(i)
  868.                 if(cm) then
  869.                     goTo(materialLocation[cm].x, materialLocation[cm].y, materialLocation[cm].z)
  870.                     emptySlot(cm,i)
  871.                 end
  872.             end
  873.         end
  874.     end
  875.    
  876.     -- Refilling
  877.     goTo(materialLocation[m].x, materialLocation[m].y, materialLocation[m].z)
  878.     local slotsToFill = {}
  879.    
  880.     if not(materialLocation[m].locked) then
  881.         for i = 1, 16 do
  882.             if i~=fuelSlot then
  883.                 table.insert(slotsToFill,i)
  884.             end
  885.         end
  886.     else
  887.         slotsToFill = materialLocation[m].locked
  888.     end
  889.    
  890.     for i, slot in pairs(slotsToFill) do
  891.         if fillSlot(m, slot) then shipped = true end
  892.     end
  893.    
  894.     if not(shipped) then waitForMaterials(m) end
  895.     lba_log("Materials shipped. Going back to Work")
  896.    
  897.     goTo(autoDetectEndPosition.x, autoDetectEndPosition.y, autoDetectEndPosition.z)
  898.     turtleStates.isGoingForMaterials = false
  899.     goTo(xs, ys, zs)
  900. end
  901.  
  902. -----------------------------------------------------------------------------
  903. -- BUILDING RELATED FUNCTIONS
  904. -----------------------------------------------------------------------------
  905. function placeBlock(m)
  906. --@params       m       string      Material to be placed
  907. --@return               boolean     True if placed
  908.     -- Check for material in inventory
  909.     local hasMaterials = false
  910.        
  911.     if(materialLocation[m].locked) then
  912.         for i, slot in pairs(materialLocation[m].locked) do
  913.             if turtle.getItemCount(slot) > 1 then
  914.                 turtle.select(slot)
  915.                 hasMaterials = true
  916.                 break
  917.             end
  918.         end
  919.     else
  920.         local cm = lba_getSlotContent(turtle.getSelectedSlot())
  921.         if cm == m then
  922.             hasMaterials = true
  923.         else
  924.             for i=1,16 do
  925.                 cm = lba_getSlotContent(i)
  926.                 if cm == m then
  927.                     turtle.select(i)
  928.                     hasMaterials = true
  929.                 end
  930.             end
  931.         end
  932.     end
  933.    
  934.     if not(hasMaterials) and autoRefillEnabled then goRefill(m)
  935.     elseif not(hasMaterials) then waitForMaterials(m) end
  936.    
  937.     if(turtle.placeDown()) then
  938.         totalBlocks = totalBlocks + 1
  939.         return true
  940.     else -- Try to remove that prevents block placing
  941.         if autoDig then turtle.digDown() end
  942.         if autoAttack then turtle.attackDown() end
  943.         if(turtle.placeDown()) then
  944.             totalBlocks = totalBlocks + 1
  945.             return true
  946.         end
  947.     end
  948. end
  949.  
  950. function dot(x, y, z, m)
  951. --@params   x, y, z     Number      Coordinates
  952. --          m           String      Material to be used
  953. --@return               nil
  954.    
  955.     turtleStates.isBuilding = true
  956.     goTo(x, y+1, z)
  957.     placeBlock(m)
  958.     turtleStates.isBuilding = false
  959. end
  960.  
  961. function line(x1, y1, z1, x2, y2, z2, m)
  962. --@params   x1, y1, z1  Number      Start coordinates
  963. --          x2, y2, z2  Number      End coordinates
  964. --          m           String      Material to be used
  965. --@return               nil
  966.     if (y2 < y1) then
  967.         local c = x2
  968.         x2 = x1
  969.         x1 = c
  970.         c = y2
  971.         y2 = y1
  972.         y1 = c
  973.         c = z2
  974.         z1 = c
  975.     end
  976.        
  977.     turtleStates.isBuilding = true
  978.     tx = math.abs(x2-x1)
  979.     ty = math.abs(y2-y1)
  980.     tz = math.abs(z2-z1)
  981.     tmax = math.max(tx,ty,tz)
  982.     if tmax == 0 then dot(x1, y1, z1, m) end -- It's a dot, not a line
  983.     for t=0, tmax do
  984.         local x = math.floor((x2-x1)*t/tmax + x1 + 0.5)
  985.         local y = math.floor((y2-y1)*t/tmax + y1 + 1.5)
  986.         local z = math.floor((z2-z1)*t/tmax + z1 + 0.5)
  987.         goTo(x,y,z)
  988.         placeBlock(m)
  989.     end
  990.     turtleStates.isBuilding = false
  991. end
  992.  
  993. function rectangleY (x1, z1, x2, z2, y, m, filled, thickness)
  994. --@params   x1, z1      Number      Start coordinates
  995. --          x2, z2      Number      End coordinates
  996. --          y           Number      Rectangle height
  997. --          m           String      Material to be used
  998. --          filled      Boolean     Filled rectangle
  999. --          thickness   Number      Border width if not filled
  1000. --@return               nil
  1001.     filled = filled or false
  1002.     thickness = thickness or 1
  1003.    
  1004.     turtleStates.isBuilding = true
  1005.     --Shortest start point
  1006.     local dTo1 = turtlePosition - vector.new(x1,y1,z1)
  1007.     local dTo2 = turtlePosition - vector.new(x2,y2,z2)
  1008.        
  1009.     if dTo1:length() <= dTo2:length() then
  1010.         xs = x1
  1011.         zs = z1
  1012.         xe = x2
  1013.         ze = z2
  1014.     else
  1015.         xs = x2
  1016.         zs = z2
  1017.         xe = x1
  1018.         ze = z1
  1019.     end
  1020.        
  1021.     local ix = (xe-xs)/math.abs(xe-xs)
  1022.     local iz = (ze-zs)/math.abs(ze-zs)
  1023.     local n=1
  1024.     local checkUneven = false
  1025.    
  1026.     if filled then
  1027.         n = math.floor(math.min(math.abs(xe-xs),math.abs(ze-zs))/2) - 1
  1028.         checkUneven = true
  1029.     else
  1030.         n = thickness - 1
  1031.     end
  1032.    
  1033.     for i=0, n do
  1034.         line(xs+i*ix, y, zs+i*iz, xe-(i+1)*ix, y, zs+i*iz, m)
  1035.         line(xe-i*ix, y, zs+i*iz, xe-i*ix, y, ze-(i+1)*iz, m)
  1036.         line(xe-i*ix, y, ze-i*iz, xs+(i+1)*ix, y, ze-i*iz, m)
  1037.         line(xs+i*ix, y, ze-i*iz, xs+i*ix, y, zs+(i+1)*iz, m)
  1038.         if (i==n) and checkUneven then -- Case of uneven shortest side size
  1039.             if ((xe-xs)<=(ze-zs)) and not((xe-xs+1)%2==0) then
  1040.                 if (zs+(i+1)*iz) == (ze-(i+1)*iz) then -- One dot for finish when square
  1041.                     dot(xs+(i+1)*ix, y, zs+(i+1)*iz, m)
  1042.                 else -- line to finish
  1043.                     line(xs+(i+1)*ix, y, zs+(i+1)*iz, xs+(i+1)*ix, y, ze-(i+1)*iz, m)
  1044.                 end
  1045.             elseif ((xe-xs)>(ze-zs)) and not((ze-zs+1)%2==0) then
  1046.                 line(xs+(i+1)*ix, y, zs+(i+1)*iz, xe-(i+1)*ix, y, zs+(i+1)*iz, m)
  1047.             end
  1048.         end
  1049.     end
  1050.    
  1051. end
  1052.  
  1053. function xmobFloor(x1, z1, x2, z2, y, m)
  1054. --@params   x, z    Number  Starting point coordinates
  1055. --          z       Number  Height
  1056. --          m       String  Material to be used
  1057.     local xt = x1 + (x2-x1)/2; -- Horizontal offset for computing
  1058.     local zt = z1 + (z2-z1)/2; -- vertical offset for computing
  1059.     local startx = 0
  1060.     local endx = 0
  1061.     local incrementx = 0
  1062.     local b = 0
  1063.    
  1064.     goTo(x1,y+1,z1)
  1065.     for zi = z1, z2 do
  1066.         if turtlePosition.x == x1 then
  1067.             startx = x1
  1068.             endx = x2
  1069.             incrementx = 1
  1070.         else
  1071.             startx = x2
  1072.             endx = x1
  1073.             incrementx = -1
  1074.         end
  1075.         for xi = startx, endx, incrementx do
  1076.             goTo(xi,y+1,zi)
  1077.             -- Calculator for x-shape
  1078.             b = math.abs(math.abs(zi-zt)-math.abs(xi-xt))
  1079.             if b >= 3 then placeBlock(m) end
  1080.         end
  1081.     end
  1082. end
  1083.  
  1084. lba_initialize()
  1085. lba_yourBuild()
  1086. lba_end()
Add Comment
Please, Sign In to add comment