Advertisement
Te-ki

CCChoper

Mar 22nd, 2025 (edited)
286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 25.65 KB | Gaming | 0 0
  1.  
  2. local tArgs = { ... }
  3. local monitor = term.current()
  4. local sizeX,sizeY = monitor.getSize()
  5.  
  6. local makeCharcoal = false
  7. local fuelPriority = {
  8.     "minecraft:stick",
  9.     "minecraft:charcoal",
  10.     "minecraft:oak_log",
  11. }
  12. local origin = {X = 0, Y = 0, Z = 0, direction = 0}
  13. local curPosition = {
  14.     X = 0,
  15.     Y = 0,
  16.     Z = 0,
  17.     direction = 0
  18. }
  19. local lastPosition = {
  20.     X = 0,
  21.     Y = 0,
  22.     Z = 0,
  23.     direction = 0
  24. }
  25. local targetPosition = {
  26.     X = 0,
  27.     Y = 0,
  28.     Z = 0,
  29.     direction = nil
  30. }
  31. local chestSide = nil
  32. local furnaceSide = nil
  33. local currentState = "setup"
  34. local lastPositionStack = {}
  35.  
  36. -- Logging
  37.  
  38. local lastMsg = ""
  39. local lastMsgCount = 0
  40. local function pmsg(msg)
  41.     if lastMsg == msg then
  42.         lastMsgCount = lastMsgCount + 1
  43.         msg = msg .. " " .. lastMsgCount
  44.     else
  45.         lastMsg = msg
  46.         lastMsgCount = 0
  47.         monitor.scroll(1)
  48.     end
  49.     monitor.setCursorPos(1,13)
  50.     monitor.clearLine()
  51.     monitor.write(msg)
  52. end
  53.  
  54. -- Utility
  55.  
  56. local function indexOf(array, needle)
  57.     for index, value in ipairs(array) do
  58.         if value == needle then
  59.             return index
  60.         end
  61.     end
  62.     return false
  63. end
  64.  
  65. local function copyPosition(position)
  66.     local newPosition = {}
  67.     newPosition.X = position.X
  68.     newPosition.Y = position.Y
  69.     newPosition.Z = position.Z
  70.     newPosition.direction = position.direction
  71.     return newPosition
  72. end
  73.  
  74. local function arePositionEquals(pos1, pos2, checkDirection)
  75.     if pos1.X == pos2.X and pos1.Y == pos2.Y and pos1.Z == pos2.Z then
  76.         if checkDirection then
  77.             return pos1.direction == pos2.direction
  78.         else
  79.             return true
  80.         end
  81.     end
  82.     return false
  83. end
  84.  
  85. -- save / Load
  86.  
  87. local filePath = "ccchop.save"
  88. local function save()
  89.     if currentState == "chopping" then
  90.         lastPositionStack[#lastPositionStack+1] = copyPosition(curPosition)
  91.         pmsg("new stack")
  92.         -- lastPositionStack[#lastPositionStack].direction = (curPosition.direction + 2) % 4
  93.     elseif currentState == "going_back" and #lastPositionStack > 1 then
  94.         if curPosition.X == lastPositionStack[#lastPositionStack].X and curPosition.Y == lastPositionStack[#lastPositionStack].Y and curPosition.Z == lastPositionStack[#lastPositionStack].Z then
  95.             lastPositionStack[#lastPositionStack] = nil
  96.             pmsg("stack removed")
  97.         end
  98.     end
  99.     -- disable save
  100.     if true then
  101.         return nil
  102.     end
  103.     if curPosition.direction > 3 then
  104.         curPosition.direction = curPosition.direction - 4
  105.     elseif curPosition.direction < 0 then
  106.         curPosition.direction = curPosition.direction + 4
  107.     end
  108.     local savedFile = fs.open(filePath, "w")
  109.     local savedValues = {
  110.         [1] = curPosition,
  111.         [2] = lastPosition,
  112.         [3] = targetPosition,
  113.         [4] = chestSide,
  114.         [5] = furnaceSide,
  115.         [6] = currentState,
  116.         [7] = lastPositionStack,
  117.     }
  118.     savedFile.write(textutils.serialize(savedValues))
  119.     savedFile.flush()
  120.     savedFile.close()
  121. end
  122. local function load()
  123.     if fs.exists(filePath) and fs.getSize(filePath) > 0 and #tArgs == 0 then
  124.         local savedFile = fs.open(filePath, "r")
  125.         local savedValues = textutils.unserialize(savedFile.readAll())
  126.  
  127.         curPosition = savedValues[1]
  128.         lastPosition = savedValues[2]
  129.         targetPosition = savedValues[3]
  130.         chestSide = savedValues[4]
  131.         furnaceSide = savedValues[5]
  132.         currentState = savedValues[6]
  133.         lastPositionStack = savedValues[7]
  134.  
  135.         savedFile.close()
  136.     end
  137. end
  138. load()
  139. save()
  140.  
  141. -- Setup
  142.  
  143. local function findPeripherals()
  144.     chestSide = nil
  145.     furnaceSide = nil
  146.     local sides = peripheral.getNames()
  147.     for i=1, #sides do
  148.         if peripheral.getType(sides[i]) == "minecraft:chest" then
  149.             chestSide = sides[i]
  150.         elseif peripheral.getType(sides[i]) == "minecraft:furnace" then
  151.             furnaceSide = sides[i]
  152.         end
  153.     end
  154.     return chestSide ~= nil and furnaceSide ~= nil
  155. end
  156.  
  157. -- Block/Item Check
  158.  
  159. local function isSapling(itemName)
  160.     return string.match(itemName, "_sapling$") ~= nil
  161. end
  162.  
  163. local function isLog(itemName)
  164.     return string.match(itemName, "_log$") ~= nil
  165. end
  166.  
  167. local function isLeaves(itemName)
  168.     return string.match(itemName, "_leaves$") ~= nil
  169. end
  170.  
  171. local function shouldMineBlock(direction, allowLeaves)
  172.     allowLeaves = (allowLeaves == nil) or allowLeaves
  173.     local turtleInspect = turtle.inspect
  174.     if direction == "up" then
  175.         turtleInspect = turtle.inspectUp
  176.     elseif direction == "down" then
  177.         turtleInspect = turtle.inspectDown
  178.     end
  179.     local success, frontItem = turtleInspect()
  180.     if success and (isLog(frontItem.name) or (allowLeaves and isLeaves(frontItem.name))) then
  181.         return true
  182.     end
  183.     return false
  184. end
  185.  
  186. local function suckItems()
  187.     if not turtle.detect() then
  188.         turtle.suck()
  189.     end
  190.     if not turtle.detectUp() then
  191.         turtle.suckUp()
  192.     end
  193.     if not turtle.detectDown() then
  194.         turtle.suckDown()
  195.     end
  196. end
  197.  
  198. -- Movement
  199.  
  200. local function moveUp()
  201.     suckItems()
  202.     if turtle.up() then
  203.         curPosition.Z = curPosition.Z + 1
  204.         save()
  205.         return true
  206.     else
  207.         while shouldMineBlock("up") and turtle.digUp() do
  208.         end
  209.         if not turtle.detectUp() then
  210.             turtle.attackUp()
  211.         end
  212.         return false
  213.     end
  214. end
  215.  
  216. local function moveDown()
  217.     suckItems()
  218.     if turtle.down() then
  219.         curPosition.Z = curPosition.Z - 1
  220.         save()
  221.         return true
  222.     else
  223.         while shouldMineBlock("down") and turtle.digDown() do
  224.         end
  225.         if not turtle.detectDown() then
  226.             turtle.attackDown()
  227.         end
  228.         return false
  229.     end
  230. end
  231.  
  232. -- Fonction pour avancer et gérer les obstacles
  233. local function moveForward(curPosition, axis)
  234.     suckItems()
  235.     if turtle.forward() then
  236.         curPosition[axis] = curPosition[axis] + ((curPosition.direction == 0 or curPosition.direction == 1) and 1 or -1)
  237.         save()
  238.         return true
  239.     else
  240.         while shouldMineBlock("front") and turtle.dig() do
  241.         end
  242.         if not turtle.detect() then
  243.             turtle.attack()
  244.         end
  245.         return false
  246.     end
  247. end
  248. -- Fonction pour tourner à droite
  249. local function turnRight()
  250.     suckItems()
  251.     if turtle.turnRight() then
  252.         curPosition.direction = (curPosition.direction + 1) % 4
  253.         save()
  254.     end
  255. end
  256. -- Fonction pour tourner à gauche
  257. local function turnLeft()
  258.     suckItems()
  259.     if turtle.turnLeft() then
  260.         curPosition.direction = (curPosition.direction + 3) % 4
  261.         save()
  262.     end
  263. end
  264. -- Fonction pour faire demi-tour
  265. local function turnAround()
  266.     turnLeft()
  267.     turnLeft()
  268. end
  269. local function moveToTarget()
  270.     -- Si on doit monter on commence par monter
  271.     if curPosition.Z < targetPosition.Z then
  272.         return moveUp()
  273.     -- Vérifiez la direction actuelle de la turtle
  274.     elseif curPosition.X ~= targetPosition.X or curPosition.Y ~= targetPosition.Y then
  275.         if curPosition.direction == 0 then -- Nord
  276.             if curPosition.X < targetPosition.X then
  277.                 return moveForward(curPosition, "X")
  278.             elseif curPosition.X > targetPosition.X then
  279.                 turnAround()
  280.                 return moveForward(curPosition, "X")
  281.             elseif curPosition.Y < targetPosition.Y then
  282.                 turnRight()
  283.                 return moveForward(curPosition, "Y")
  284.             elseif curPosition.Y > targetPosition.Y then
  285.                 turnLeft()
  286.                 return moveForward(curPosition, "Y")
  287.             end
  288.         elseif curPosition.direction == 1 then -- Est
  289.             if curPosition.Y < targetPosition.Y then
  290.                 return moveForward(curPosition, "Y")
  291.             elseif curPosition.Y > targetPosition.Y then
  292.                 turnAround()
  293.                 return moveForward(curPosition, "Y")
  294.             elseif curPosition.X > targetPosition.X then
  295.                 turnRight()
  296.                 return moveForward(curPosition, "X")
  297.             elseif curPosition.X < targetPosition.X then
  298.                 turnLeft()
  299.                 moveForward(curPosition, "X")
  300.             end
  301.         elseif curPosition.direction == 2 then -- Sud
  302.             if curPosition.X > targetPosition.X then
  303.                 return moveForward(curPosition, "X")
  304.             elseif curPosition.X < targetPosition.X then
  305.                 turnAround()
  306.                 return moveForward(curPosition, "X")
  307.             elseif curPosition.Y > targetPosition.Y then
  308.                 turnRight()
  309.                 return moveForward(curPosition, "Y")
  310.             elseif curPosition.Y < targetPosition.Y then
  311.                 turnLeft()
  312.                 return moveForward(curPosition, "Y")
  313.             end
  314.         elseif curPosition.direction == 3 then -- Ouest
  315.             if curPosition.Y > targetPosition.Y then
  316.                 return moveForward(curPosition, "Y")
  317.             elseif curPosition.Y < targetPosition.Y then
  318.                 turnAround()
  319.                 return moveForward(curPosition, "Y")
  320.             elseif curPosition.X < targetPosition.X then
  321.                 turnRight()
  322.                 return moveForward(curPosition, "X")
  323.             elseif curPosition.X > targetPosition.X then
  324.                 turnLeft()
  325.                 return moveForward(curPosition, "X")
  326.             end
  327.         end
  328.     -- Si on doit descendre on fini par descendre
  329.     elseif curPosition.Z > targetPosition.Z then
  330.         return moveDown()
  331.     -- Enfin on aligne la direction
  332.     elseif targetPosition.direction ~= nil and curPosition.direction > targetPosition.direction then
  333.         turnLeft()
  334.     elseif targetPosition.direction ~= nil and curPosition.direction < targetPosition.direction then
  335.         turnRight()
  336.     else
  337.         save()
  338.     end
  339. end
  340.  
  341. -- Inventory
  342.  
  343. local function findItemSlotInTurtleInventory(itemName)
  344.     for slot=1, 16 do
  345.         local itemDetail = turtle.getItemDetail(slot)
  346.         if itemDetail ~= nil and itemDetail.name == itemName then
  347.             return true, slot
  348.         end
  349.     end
  350.     return false, nil
  351. end
  352.  
  353. local function findItemSlotInInventory(inventory, itemName, stackMustHaveFreeSpace)
  354.     -- TODO : use a callback to validate itemName
  355.     -- if is string use a default callback (anonymous function)
  356.     -- if is function use it as callback (and validator(itemDetail.name))
  357.     local size = inventory.size()
  358.     for slot=1, size do
  359.         local itemDetail = inventory.getItemDetail(slot)
  360.         if itemDetail ~= nil and itemDetail.name == itemName and (not stackMustHaveFreeSpace or itemDetail.count < itemDetail.maxCount) then
  361.             return slot, itemDetail
  362.         end
  363.     end
  364.     return nil
  365. end
  366.  
  367. local function findEmptySlot(itemList, size)
  368.     for slot=1, size do
  369.         if not itemList[slot] then
  370.             return true, slot
  371.         end
  372.     end
  373.     return false, nil
  374. end
  375.  
  376. local function clearFurnaceOutput()
  377.     if findPeripherals() then
  378.         local furnace = peripheral.wrap(furnaceSide)
  379.         local chest = peripheral.wrap(chestSide)
  380.         local outputSlotItemDetail = furnace.getItemDetail(3)
  381.         if outputSlotItemDetail ~= nil and outputSlotItemDetail.count > 0 then
  382.             local itemName = outputSlotItemDetail.name
  383.             local chestSlot, chestItemDetail = findItemSlotInInventory(chest, itemName, true)
  384.             while (chestSlot ~= nil and chestItemDetail ~= nil) and outputSlotItemDetail ~= nil and outputSlotItemDetail.count > 0 do
  385.                 furnace.pushItems(chestSide, 3, chestItemDetail.maxCount - chestItemDetail.count, chestSlot)
  386.                 outputSlotItemDetail = furnace.getItemDetail(3)
  387.                 chestSlot, chestItemDetail = findItemSlotInInventory(chest, itemName, true)
  388.             end
  389.             if chestSlot == nil and outputSlotItemDetail ~= nil and outputSlotItemDetail.count > 0 then
  390.                 local success, chestSlot = findEmptySlot(chest.list(), chest.size())
  391.                 if success then
  392.                     furnace.pushItems(chestSide, 3, 64, chestSlot)
  393.                 end
  394.             end
  395.             outputSlotItemDetail = furnace.getItemDetail(3)
  396.         end
  397.         return outputSlotItemDetail == nil or outputSlotItemDetail.count > 0
  398.     end
  399.     return false
  400. end
  401.  
  402. local function fillFurnaceInput()
  403.     if findPeripherals() then
  404.         local furnace = peripheral.wrap(furnaceSide)
  405.         local chest = peripheral.wrap(chestSide)
  406.        
  407.         local furnaceItemInput = furnace.getItemDetail(1)
  408.         local chestSlot, chestItemDetail = findItemSlotInInventory(chest, "minecraft:oak_log", false)
  409.         while chestSlot ~= nil and chestItemDetail ~= nil and (furnaceItemInput== nil or furnaceItemInput.count < furnaceItemInput.maxCount) do
  410.             furnaceItemInput = furnace.getItemDetail(1)
  411.             chestSlot, chestItemDetail = findItemSlotInInventory(chest, "minecraft:oak_log", false)
  412.             if chestSlot ~= nil and chestItemDetail ~= nil then
  413.                 chest.pushItems(furnaceSide, chestSlot)
  414.             end
  415.         end
  416.  
  417.         local furnaceFuelInput = furnace.getItemDetail(2)
  418.         local fuelItem = "minecraft:oak_log"
  419.         if furnaceFuelInput ~= nil and furnaceFuelInput.name ~= nil then
  420.             fuelItem = furnaceFuelInput.name
  421.         end
  422.         chestSlot, chestItemDetail = findItemSlotInInventory(chest, fuelItem, false)
  423.         while chestSlot ~= nil and chestItemDetail ~= nil and (furnaceFuelInput == nil or furnaceFuelInput.count < furnaceFuelInput.maxCount) do
  424.             furnaceFuelInput = furnace.getItemDetail(2)
  425.             chestSlot, chestItemDetail = findItemSlotInInventory(chest, fuelItem, false)
  426.             if chestSlot ~= nil and chestItemDetail ~= nil then
  427.                 chest.pushItems(furnaceSide, chestSlot)
  428.             end
  429.         end
  430.         return true
  431.     end
  432.     return false
  433. end
  434.  
  435. -- turtle must be facing, below or over the chest
  436. local function takeItemInChest(itemName)
  437.     local turtleSuck = turtle.suck
  438.     local oldChestSide = chestSide
  439.     if chestSide == "right" then
  440.         turnRight()
  441.         chestSide = "front"
  442.     elseif chestSide == "left" then
  443.         turnLeft()
  444.         chestSide = "front"
  445.     elseif chestSide == "back" then
  446.         turnAround()
  447.         chestSide = "front"
  448.     elseif chestSide == "top" then
  449.         turtleSuck = turtle.suckUp
  450.     elseif chestSide == "down" then
  451.         turtleSuck = turtle.suckDown
  452.     end
  453.  
  454.     local returnValue = false
  455.     local chest = peripheral.wrap(chestSide)
  456.     local chestItemSlot, chestItemDetail = findItemSlotInInventory(chest, itemName, false)
  457.     if chestItemSlot ~= nil then
  458.         if chestItemSlot == 1 then
  459.             turtleSuck()
  460.             returnValue = true
  461.         else
  462.             -- find empty slot
  463.             local success, chestEmptySlot = findEmptySlot(chest.list(), chest.size())
  464.             if success then
  465.                 if chestEmptySlot == 1 then
  466.                     -- move fuitemel to slot 1
  467.                     chest.pushItems(chestSide, chestItemSlot, chestItemDetail.count, 1)
  468.                     turtleSuck()
  469.                     returnValue = true
  470.                 else
  471.                     -- move slot 1 to empty slot
  472.                     chest.pushItems(chestSide, 1, 64, chestEmptySlot)
  473.                     -- move item to slot 1
  474.                     chest.pushItems(chestSide, chestItemSlot, chestItemDetail.count, 1)
  475.                     turtleSuck()
  476.                     returnValue = true
  477.                 end
  478.             end
  479.         end
  480.     end
  481.    
  482.     if oldChestSide == "right" then
  483.         turnLeft()
  484.     elseif oldChestSide == "left" then
  485.         turnRight()
  486.     elseif oldChestSide == "back" then
  487.         turnAround()
  488.     end
  489.     chestSide = oldChestSide
  490.  
  491.     return returnValue
  492. end
  493.  
  494. local function clearTurtleInventory()
  495.     local needEmptying = false
  496.     local fuelItem = nil
  497.     for slot=1, 16 do
  498.         local itemDetail = turtle.getItemDetail(slot)
  499.         if itemDetail ~= nil and not (indexOf(fuelPriority, itemDetail.name) or isSapling(itemDetail.name) or itemDetail.name == "minecraft:bone_meal") then
  500.             needEmptying = true
  501.             break
  502.         elseif itemDetail ~= nil and fuelItem == nil and indexOf(fuelPriority, itemDetail.name) then
  503.             fuelItem = fuelPriority[indexOf(fuelPriority, itemDetail.name)]
  504.         elseif itemDetail ~= nil and fuelItem ~= nil and indexOf(fuelPriority, itemDetail.name) and fuelItem ~= fuelPriority[indexOf(fuelPriority, itemDetail.name)] then
  505.             needEmptying = true
  506.             break
  507.         end
  508.     end
  509.     if not needEmptying then
  510.         return true
  511.     end
  512.     if findPeripherals() then
  513.         local turtleDrop = turtle.drop
  514.         local oldChestSide = chestSide
  515.         if chestSide == "right" then
  516.             turnRight()
  517.             chestSide = "front"
  518.         elseif chestSide == "left" then
  519.             turnLeft()
  520.             chestSide = "front"
  521.         elseif chestSide == "back" then
  522.             turnAround()
  523.             chestSide = "front"
  524.         elseif chestSide == "top" then
  525.             turtleDrop = turtle.dropUp
  526.         elseif chestSide == "down" then
  527.             turtleDrop = turtle.dropDown
  528.         end
  529.         local chest = peripheral.wrap(chestSide)
  530.         local fuelSlot = {slot = 0, count = 0, maxCount = 0, name = nil}
  531.         local saplingSlot = {slot = 0, count = 0, maxCount = 0, name = nil}
  532.         local fertilizerSlot = {slot = 0, count = 0, maxCount = 0, name = nil}
  533.         for slot=1, 16 do
  534.             if not findEmptySlot(chest.list(), chest.size()) then
  535.                 return false
  536.             end
  537.             local itemDetail = turtle.getItemDetail(slot, true)
  538.             if itemDetail ~= nil then
  539.                 -- c'est un log
  540.                 if isLog(itemDetail.name) then
  541.                     turtle.select(slot)
  542.                     turtleDrop()
  543.                 -- c'est un fuel et je n'en ai pas
  544.                 elseif fuelSlot.name == nil and indexOf(fuelPriority, itemDetail.name) then
  545.                     for fuelIndex = 1, #fuelPriority do
  546.                         if itemDetail.name == fuelPriority[fuelIndex] then
  547.                             fuelSlot.name = itemDetail.name
  548.                             fuelSlot.count = itemDetail.count
  549.                             fuelSlot.maxCount = itemDetail.maxCount
  550.                             fuelSlot.slot = slot
  551.                         end
  552.                     end
  553.                 -- c'est mon fuel et j'ai de la place
  554.                 elseif itemDetail.name == fuelSlot.name and fuelSlot.count < fuelSlot.maxCount then
  555.                     turtle.select(slot)
  556.                     turtle.transferTo(fuelSlot.slot, fuelSlot.maxCount - fuelSlot.count)
  557.                     local fuelDetail = turtle.getItemDetail(fuelSlot.slot, true)
  558.                     if fuelDetail ~= nil then
  559.                         fuelSlot.count = fuelDetail.count
  560.                     end
  561.                     -- c'est mon fuel et j'avais de la place mais je n'en ai plus
  562.                     if itemDetail.count > (fuelSlot.maxCount - fuelSlot.count) then
  563.                         turtleDrop()
  564.                     end
  565.                 -- c'est un sapling et je n'en ai pas
  566.                 elseif saplingSlot.name == nil and isSapling(itemDetail.name) then
  567.                     saplingSlot.name = itemDetail.name
  568.                     saplingSlot.count = itemDetail.count
  569.                     saplingSlot.maxCount = itemDetail.maxCount
  570.                     saplingSlot.slot = slot
  571.                 -- c'est mon sapling et j'ai de la place
  572.                 elseif itemDetail.name == saplingSlot.name and saplingSlot.count < saplingSlot.maxCount then
  573.                     turtle.select(slot)
  574.                     turtle.transferTo(saplingSlot.slot, saplingSlot.maxCount - saplingSlot.count)
  575.                     local saplingDetail = turtle.getItemDetail(saplingSlot.slot, true)
  576.                     if saplingDetail ~= nil then
  577.                         saplingSlot.count = saplingDetail.count
  578.                     end
  579.                     -- c'est mon sapling et j'avais de la place mais je n'en ai plus
  580.                     if itemDetail.count > (saplingSlot.maxCount - saplingSlot.count) then
  581.                         turtleDrop()
  582.                     end
  583.                 -- c'est un fertilizer et je n'en ai pas
  584.                 elseif fertilizerSlot.name == nil and itemDetail.name == "minecraft:bone_meal" then
  585.                     fertilizerSlot.name = itemDetail.name
  586.                     fertilizerSlot.count = itemDetail.count
  587.                     fertilizerSlot.maxCount = itemDetail.maxCount
  588.                     fertilizerSlot.slot = slot
  589.                 -- c'est mon sapling et j'ai de la place
  590.                 elseif itemDetail.name == fertilizerSlot.name and fertilizerSlot.count < fertilizerSlot.maxCount then
  591.                     turtle.select(slot)
  592.                     turtle.transferTo(fertilizerSlot.slot, fertilizerSlot.maxCount - fertilizerSlot.count)
  593.                     local fertilizerDetail = turtle.getItemDetail(fertilizerSlot.slot, true)
  594.                     if fertilizerDetail ~= nil then
  595.                         fertilizerSlot.count = fertilizerDetail.count
  596.                     end
  597.                     -- c'est mon sapling et j'avais de la place mais je n'en ai plus
  598.                     if itemDetail.count > (fertilizerSlot.maxCount - fertilizerSlot.count) then
  599.                         turtleDrop()
  600.                     end
  601.                 else
  602.                     turtle.select(slot)
  603.                     turtleDrop()
  604.                 end
  605.                 turtle.select(1)
  606.             end
  607.         end
  608.         if saplingSlot.name == nil or saplingSlot.count < saplingSlot.maxCount then
  609.             -- search sapling in chest ?
  610.             takeItemInChest("minecraft:oak_sapling")
  611.         end
  612.         if fuelSlot.name == nil or fuelSlot.count < fuelSlot.maxCount then
  613.             -- search fuel in chest ?
  614.             if fuelSlot.name ~= nil then
  615.                 takeItemInChest(fuelSlot.name)
  616.             else
  617.                 for fuelIndex = 1, #fuelPriority do
  618.                     if takeItemInChest(fuelPriority[fuelIndex]) then
  619.                         break
  620.                     end
  621.                 end
  622.             end
  623.         end
  624.         turtle.select(1)
  625.         if oldChestSide == "right" then
  626.             turnLeft()
  627.         elseif oldChestSide == "left" then
  628.             turnRight()
  629.         elseif oldChestSide == "back" then
  630.             turnAround()
  631.         end
  632.         chestSide = oldChestSide
  633.         return true
  634.     end
  635.     return false
  636. end
  637.  
  638. local function useFertilizer()
  639.     local success, fertilizerSlot = findItemSlotInTurtleInventory("minecraft:bone_meal")
  640.     if success then
  641.         turtle.select(fertilizerSlot)
  642.         turtle.place()
  643.         turtle.select(1)
  644.     end
  645. end
  646.  
  647. local function refuel()
  648.     local minimumFuelAMount = (math.abs(curPosition.X) + math.abs(curPosition.Y) + math.abs(curPosition.Z)) + 200
  649.     if turtle.getFuelLevel() > minimumFuelAMount then
  650.         return true
  651.     end
  652.     local success, fuelSlot
  653.     for fuelIndex = 1, #fuelPriority do
  654.         success, fuelSlot = findItemSlotInTurtleInventory(fuelPriority[fuelIndex])
  655.         if success then
  656.             turtle.select(fuelSlot)
  657.             local itemDetail = turtle.getItemDetail(fuelSlot)
  658.             turtle.refuel(itemDetail.count)
  659.             turtle.select(1)
  660.             if turtle.getFuelLevel() > minimumFuelAMount then
  661.                 return true
  662.             end
  663.         end
  664.         success = takeItemInChest(fuelPriority[fuelIndex])
  665.         if success then
  666.             success, fuelSlot = findItemSlotInTurtleInventory(fuelPriority[fuelIndex])
  667.             if success then
  668.                 turtle.select(fuelSlot)
  669.                 local itemDetail = turtle.getItemDetail(fuelSlot)
  670.                 turtle.refuel(itemDetail.count)
  671.                 turtle.select(1)
  672.                 if turtle.getFuelLevel() > minimumFuelAMount then
  673.                     return true
  674.                 end
  675.             end
  676.         end
  677.     end
  678.     return turtle.getFuelLevel() > minimumFuelAMount
  679. end
  680.  
  681. local function recursiveChopping()
  682.     local mineLeaves = true
  683.     for i = 1, 1 do
  684.         if shouldMineBlock("down", mineLeaves) then
  685.             while shouldMineBlock("down", mineLeaves) and turtle.digDown() do
  686.             end
  687.             if moveDown() then
  688.                 recursiveChopping()
  689.                 moveUp()
  690.             end
  691.         end
  692.    
  693.         if shouldMineBlock("up", mineLeaves) then
  694.             while shouldMineBlock("up", mineLeaves) and turtle.digUp() do
  695.             end
  696.             if moveUp() then
  697.                 recursiveChopping()
  698.                 moveDown()
  699.             end
  700.         end
  701.        
  702.         local sidesSeen = {0, 0, 0, 0}
  703.         for turn = curPosition.direction, curPosition.direction + 3 do
  704.             local oldPosition = copyPosition(curPosition)
  705.             local newPosition = copyPosition(curPosition)
  706.    
  707.             if shouldMineBlock("front", mineLeaves) then
  708.                 while shouldMineBlock("front", mineLeaves) and turtle.dig() do
  709.                 end
  710.                 if newPosition.direction == 0 or newPosition.direction == 2 then -- Nord ou Sud
  711.                     newPosition.X = newPosition.X + (newPosition.direction == 0 and 1 or -1)
  712.                 elseif newPosition.direction == 1 or curPosition.direction == 3 then -- Est ou Ouest
  713.                     newPosition.Y = newPosition.Y + (newPosition.direction == 1 and 1 or -1)
  714.                 end
  715.    
  716.                 targetPosition = copyPosition(newPosition)
  717.                 while not arePositionEquals(curPosition, targetPosition, true) do
  718.                     moveToTarget()
  719.                 end
  720.    
  721.                 recursiveChopping()
  722.    
  723.                 -- targetPosition = copyPosition(oldPosition)
  724.                 -- moveToTarget()
  725.             end
  726.    
  727.             -- turnToUnseenSide
  728.             newPosition = copyPosition(oldPosition)
  729.             sidesSeen[oldPosition.direction] = 1
  730.             if sidesSeen[(oldPosition.direction + 1) % 4] ~= 1 then
  731.                 newPosition.direction = (oldPosition.direction + 1) % 4
  732.             elseif sidesSeen[(oldPosition.direction - 1) % 4] ~= 1 then
  733.                 newPosition.direction = (oldPosition.direction - 1) % 4
  734.             elseif sidesSeen[(oldPosition.direction + 2) % 4] ~= 1 then
  735.                 newPosition.direction = (oldPosition.direction + 2) % 4
  736.             elseif sidesSeen[(oldPosition.direction - 2) % 4] ~= 1 then
  737.                 newPosition.direction = (oldPosition.direction - 2) % 4
  738.             elseif sidesSeen[(oldPosition.direction + 3) % 4] ~= 1 then
  739.                 newPosition.direction = (oldPosition.direction + 3) % 4
  740.             elseif sidesSeen[(oldPosition.direction - 3) % 4] ~= 1 then
  741.                 newPosition.direction = (oldPosition.direction - 3) % 4
  742.             else
  743.                 break
  744.             end
  745.             targetPosition = copyPosition(newPosition)
  746.             while not arePositionEquals(curPosition, targetPosition, true) do
  747.                 moveToTarget()
  748.             end
  749.         end
  750.         mineLeaves = true
  751.     end
  752. end
  753.  
  754. -- Main Loop
  755.  
  756. local function mainLoop()
  757.     while true do
  758.         sleep(0)
  759.         local lastState = currentState
  760.         if currentState == "setup" then
  761.             -- est-on à l'origine ?
  762.             -- les peripheriques sont-ils présents ?
  763.             if not findPeripherals() then
  764.                 pmsg("Please place a chest and a furnace next to the turtle.")
  765.                 return false;
  766.             end
  767.             -- inspecte devant, cherche un sapling
  768.             local success, frontItem = turtle.inspect()
  769.             if not success or not isSapling(frontItem.name) then
  770.                 -- si obstacle on mine ?
  771.                 while turtle.detect() and turtle.dig() do
  772.                 end
  773.                 -- si pas de sapling on en cherche dans l'inventaire
  774.                 local success, saplingSlot = findItemSlotInTurtleInventory("minecraft:oak_sapling")
  775.                 if not success then
  776.                     local success, saplingSlot = findItemSlotInTurtleInventory("minecraft:oak_sapling")
  777.                     -- sinon on n'en cherche dans le coffre
  778.                 end
  779.                 if success then
  780.                     -- enfin on le plante
  781.                     turtle.select(saplingSlot)
  782.                     turtle.place()
  783.                     turtle.select(1)
  784.                     currentState = "wait"
  785.                 else
  786.                     pmsg("Can't find sappling.")
  787.                     return false;
  788.                     -- ou si toujours pas trouvé afficher message
  789.                 end
  790.             end
  791.             currentState = "wait"
  792.         elseif currentState == "wait" then
  793.             if makeCharcoal and not clearFurnaceOutput() then
  794.                 pmsg("Chest is full")
  795.             elseif makeCharcoal and not fillFurnaceInput() then
  796.                 pmsg("Please place a chest and a furnace next to the turtle.")
  797.             elseif not clearTurtleInventory() then
  798.                 pmsg("Chest is full")
  799.             elseif makeCharcoal and not fillFurnaceInput() then
  800.                 pmsg("Please place a chest and a furnace next to the turtle.")
  801.             elseif not refuel()  then
  802.                 pmsg("Can't refuel")
  803.                 -- we do nothing, not enought fuel
  804.             elseif #lastPositionStack > 1 then
  805.                 targetPosition = lastPositionStack[#lastPositionStack]
  806.                 moveToTarget()
  807.                 pmsg("Move to target " .. #lastPositionStack)
  808.             else
  809.                 pmsg("Inspect")
  810.                 local success, frontItem = turtle.inspect()
  811.                 if success and isLog(frontItem.name) then
  812.                
  813.                     recursiveChopping()
  814.                     currentState = "going_back"
  815.                 elseif success and isSapling(frontItem.name) then
  816.                     useFertilizer()
  817.                 end
  818.             end
  819.         elseif currentState == "going_back" then
  820.             if #lastPositionStack >= 1 then
  821.                 local lastPositionInStack = lastPositionStack[#lastPositionStack]
  822.                 if curPosition.X == lastPositionInStack.X and curPosition.Y == lastPositionInStack.Y and curPosition.Z == lastPositionInStack.Z then
  823.                     lastPositionStack[#lastPositionStack] = nil
  824.                 end
  825.                 if #lastPositionStack >= 1 then
  826.                     targetPosition = lastPositionStack[#lastPositionStack]
  827.                     moveToTarget()
  828.                 end
  829.             elseif curPosition.X ~= 0 or curPosition.Y ~= 0 or curPosition.Z ~= 0 or curPosition.direction ~= 0 then
  830.                 targetPosition = origin
  831.                 moveToTarget()
  832.             else
  833.                 currentState = "setup"
  834.             end
  835.         end
  836.         if lastState ~= currentState then
  837.             pmsg(currentState)
  838.         end
  839.     end
  840. end
  841. mainLoop()
  842. -- parallel.waitForAll(mainLoop, drawLoop)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement