robathome

deforestation

Oct 6th, 2026
24,549
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.70 KB | None | 0 0
  1. -- ============================================================
  2. -- Six-tree automatic tree farm
  3. -- For a ComputerCraft / CC:Tweaked Felling Turtle
  4. --
  5. -- Starting position:
  6. -- X = 286
  7. -- Z = 108
  8. -- Y = 63
  9. --
  10. -- IMPORTANT:
  11. -- Turtle must start facing +Z (toward Z=109,110,...)
  12. --
  13. -- Chest must be directly UNDER the turtle's starting position.
  14. -- ============================================================
  15.  
  16.  
  17. -- ------------------------------------------------------------
  18. -- CONFIGURATION
  19. -- ------------------------------------------------------------
  20.  
  21. local HOME_X = 286
  22. local HOME_Z = 108
  23.  
  24. -- Tree coordinates, expressed as X/Z because all are at Y=63.
  25. local trees = {
  26. { x = 284, z = 110 },
  27. { x = 288, z = 110 },
  28.  
  29. { x = 284, z = 114 },
  30. { x = 288, z = 114 },
  31.  
  32. { x = 284, z = 118 },
  33. { x = 288, z = 118 }
  34. }
  35.  
  36. -- How long to wait between complete farm checks.
  37. local CHECK_INTERVAL = 30
  38.  
  39. -- Maximum bone-meal attempts before giving up on a sapling.
  40. local MAX_BONEMEAL_ATTEMPTS = 32
  41.  
  42. -- Refuel if below this amount.
  43. local MIN_FUEL = 250
  44.  
  45.  
  46. -- ------------------------------------------------------------
  47. -- POSITION TRACKING
  48. -- ------------------------------------------------------------
  49. --
  50. -- Direction:
  51. -- 0 = +Z
  52. -- 1 = -X
  53. -- 2 = -Z
  54. -- 3 = +X
  55. --
  56. -- We start facing +Z.
  57. -- ------------------------------------------------------------
  58.  
  59. local posX = HOME_X
  60. local posZ = HOME_Z
  61. local direction = 0
  62.  
  63.  
  64. local function turnLeft()
  65. turtle.turnLeft()
  66. direction = (direction + 1) % 4
  67. end
  68.  
  69.  
  70. local function turnRight()
  71. turtle.turnRight()
  72. direction = (direction + 3) % 4
  73. end
  74.  
  75.  
  76. local function face(target)
  77. while direction ~= target do
  78. turnRight()
  79. end
  80. end
  81.  
  82.  
  83. local function forward()
  84. local attempts = 0
  85.  
  86. while not turtle.forward() do
  87. attempts = attempts + 1
  88.  
  89. if attempts > 20 then
  90. error("Unable to move forward.")
  91. end
  92.  
  93. -- Don't automatically destroy random obstacles.
  94. sleep(0.25)
  95. end
  96.  
  97. if direction == 0 then
  98. posZ = posZ + 1
  99. elseif direction == 1 then
  100. posX = posX - 1
  101. elseif direction == 2 then
  102. posZ = posZ - 1
  103. elseif direction == 3 then
  104. posX = posX + 1
  105. end
  106. end
  107.  
  108.  
  109. local function back()
  110. local attempts = 0
  111.  
  112. while not turtle.back() do
  113. attempts = attempts + 1
  114.  
  115. if attempts > 20 then
  116. error("Unable to move backward.")
  117. end
  118.  
  119. sleep(0.25)
  120. end
  121.  
  122. if direction == 0 then
  123. posZ = posZ - 1
  124. elseif direction == 1 then
  125. posX = posX + 1
  126. elseif direction == 2 then
  127. posZ = posZ + 1
  128. elseif direction == 3 then
  129. posX = posX - 1
  130. end
  131. end
  132.  
  133.  
  134. -- ------------------------------------------------------------
  135. -- NAVIGATION
  136. -- ------------------------------------------------------------
  137.  
  138. local function moveTo(x, z)
  139.  
  140. -- X movement
  141. if posX < x then
  142. face(3) -- +X
  143.  
  144. while posX < x do
  145. forward()
  146. end
  147.  
  148. elseif posX > x then
  149. face(1) -- -X
  150.  
  151. while posX > x do
  152. forward()
  153. end
  154. end
  155.  
  156.  
  157. -- Z movement
  158. if posZ < z then
  159. face(0) -- +Z
  160.  
  161. while posZ < z do
  162. forward()
  163. end
  164.  
  165. elseif posZ > z then
  166. face(2) -- -Z
  167.  
  168. while posZ > z do
  169. forward()
  170. end
  171. end
  172. end
  173.  
  174.  
  175. local function goHome()
  176. moveTo(HOME_X, HOME_Z)
  177. face(0)
  178. end
  179.  
  180.  
  181. -- ------------------------------------------------------------
  182. -- ITEM IDENTIFICATION
  183. -- ------------------------------------------------------------
  184.  
  185. local function endsWith(text, suffix)
  186. return text:sub(-#suffix) == suffix
  187. end
  188.  
  189.  
  190. local function isSaplingName(name)
  191. if not name then
  192. return false
  193. end
  194.  
  195. return endsWith(name, "_sapling") or
  196. name == "minecraft:mangrove_propagule"
  197. end
  198.  
  199.  
  200. local function isLogName(name)
  201. if not name then
  202. return false
  203. end
  204.  
  205. return endsWith(name, "_log") or
  206. endsWith(name, "_wood") or
  207. endsWith(name, "_stem") or
  208. endsWith(name, "_hyphae")
  209. end
  210.  
  211.  
  212. local function isFuelName(name)
  213. return name == "minecraft:coal" or
  214. name == "minecraft:charcoal" or
  215. name == "minecraft:coal_block"
  216. end
  217.  
  218.  
  219. local function isBoneMealName(name)
  220. return name == "minecraft:bone_meal"
  221. end
  222.  
  223.  
  224. -- ------------------------------------------------------------
  225. -- INVENTORY SEARCH
  226. -- ------------------------------------------------------------
  227.  
  228. local function findItem(testFunction)
  229.  
  230. for slot = 1, 16 do
  231. local item = turtle.getItemDetail(slot)
  232.  
  233. if item and testFunction(item.name) then
  234. return slot, item
  235. end
  236. end
  237.  
  238. return nil
  239. end
  240.  
  241.  
  242. local function findBoneMeal()
  243. return findItem(isBoneMealName)
  244. end
  245.  
  246.  
  247. local function findAnySapling()
  248. return findItem(isSaplingName)
  249. end
  250.  
  251.  
  252. local function findExactItem(name)
  253.  
  254. for slot = 1, 16 do
  255. local item = turtle.getItemDetail(slot)
  256.  
  257. if item and item.name == name then
  258. return slot
  259. end
  260. end
  261.  
  262. return nil
  263. end
  264.  
  265.  
  266. -- ------------------------------------------------------------
  267. -- FUEL
  268. -- ------------------------------------------------------------
  269.  
  270. local function refuel()
  271.  
  272. local fuel = turtle.getFuelLevel()
  273.  
  274. if fuel == "unlimited" then
  275. return true
  276. end
  277.  
  278. if fuel >= MIN_FUEL then
  279. return true
  280. end
  281.  
  282. print("Fuel low: " .. fuel)
  283.  
  284. for slot = 1, 16 do
  285.  
  286. local item = turtle.getItemDetail(slot)
  287.  
  288. if item and isFuelName(item.name) then
  289.  
  290. turtle.select(slot)
  291.  
  292. while turtle.getItemCount(slot) > 0 and
  293. turtle.getFuelLevel() < MIN_FUEL do
  294.  
  295. turtle.refuel(1)
  296. end
  297.  
  298. if turtle.getFuelLevel() >= MIN_FUEL then
  299. print("Refueled: " .. turtle.getFuelLevel())
  300. return true
  301. end
  302. end
  303. end
  304.  
  305. print("WARNING: No fuel available!")
  306. return false
  307. end
  308.  
  309.  
  310. -- ------------------------------------------------------------
  311. -- BLOCK INSPECTION
  312. -- ------------------------------------------------------------
  313.  
  314. local function blockInFront()
  315.  
  316. local success, block = turtle.inspect()
  317.  
  318. if success then
  319. return block
  320. end
  321.  
  322. return nil
  323. end
  324.  
  325.  
  326. local function logInFront()
  327.  
  328. local block = blockInFront()
  329.  
  330. return block and isLogName(block.name)
  331. end
  332.  
  333.  
  334. local function logAbove()
  335.  
  336. local success, block = turtle.inspectUp()
  337.  
  338. return success and isLogName(block.name)
  339. end
  340.  
  341.  
  342. local function logBelow()
  343.  
  344. local success, block = turtle.inspectDown()
  345.  
  346. return success and isLogName(block.name)
  347. end
  348.  
  349.  
  350. -- ------------------------------------------------------------
  351. -- RECURSIVE TREE HARVEST
  352. --
  353. -- Turtle should be standing INSIDE the location of a log which
  354. -- it has just removed.
  355. --
  356. -- Every recursive call returns the turtle to exactly the same
  357. -- location and orientation from which that call started.
  358. -- ------------------------------------------------------------
  359.  
  360. local function harvestConnectedLogs()
  361.  
  362. -- ----- LOG ABOVE -----
  363.  
  364. if logAbove() then
  365.  
  366. turtle.digUp()
  367.  
  368. if turtle.up() then
  369.  
  370. harvestConnectedLogs()
  371.  
  372. turtle.down()
  373. end
  374. end
  375.  
  376.  
  377. -- ----- LOG BELOW -----
  378. --
  379. -- Normally the parent log has already been removed, so this
  380. -- will not cause us to walk back through the tree.
  381. --
  382. -- It also catches unusual downward-connected branches.
  383. --
  384.  
  385. if logBelow() then
  386.  
  387. turtle.digDown()
  388.  
  389. if turtle.down() then
  390.  
  391. harvestConnectedLogs()
  392.  
  393. turtle.up()
  394. end
  395. end
  396.  
  397.  
  398. -- ----- FOUR HORIZONTAL DIRECTIONS -----
  399.  
  400. for side = 1, 4 do
  401.  
  402. if logInFront() then
  403.  
  404. turtle.dig()
  405.  
  406. if turtle.forward() then
  407.  
  408. harvestConnectedLogs()
  409.  
  410. turtle.back()
  411. end
  412. end
  413.  
  414. turtle.turnRight()
  415. end
  416.  
  417. end
  418.  
  419.  
  420. -- ------------------------------------------------------------
  421. -- DETERMINE REPLACEMENT SAPLING FROM LOG TYPE
  422. -- ------------------------------------------------------------
  423.  
  424. local function saplingFromLog(logName)
  425.  
  426. if not logName then
  427. return nil
  428. end
  429.  
  430. -- minecraft:oak_log -> minecraft:oak_sapling
  431. if endsWith(logName, "_log") then
  432.  
  433. local prefix = logName:sub(1, #logName - 4)
  434.  
  435. return prefix .. "_sapling"
  436. end
  437.  
  438.  
  439. -- Wood variants
  440. if endsWith(logName, "_wood") then
  441.  
  442. local prefix = logName:sub(1, #logName - 5)
  443.  
  444. return prefix .. "_sapling"
  445. end
  446.  
  447.  
  448. return nil
  449. end
  450.  
  451.  
  452. -- ------------------------------------------------------------
  453. -- GROW SAPLING
  454. -- ------------------------------------------------------------
  455.  
  456. local function growSapling()
  457.  
  458. for attempt = 1, MAX_BONEMEAL_ATTEMPTS do
  459.  
  460. local block = blockInFront()
  461.  
  462. -- It grew.
  463. if block and isLogName(block.name) then
  464. print("Tree grew after " .. (attempt - 1) ..
  465. " bone meal attempts.")
  466.  
  467. return true, block.name
  468. end
  469.  
  470.  
  471. -- No longer a sapling and not a log.
  472. if not block or not isSaplingName(block.name) then
  473. return false, nil
  474. end
  475.  
  476.  
  477. local slot = findBoneMeal()
  478.  
  479. if not slot then
  480. print("Out of bone meal.")
  481. return false, nil
  482. end
  483.  
  484.  
  485. turtle.select(slot)
  486.  
  487. turtle.place()
  488.  
  489. sleep(0.15)
  490. end
  491.  
  492.  
  493. local block = blockInFront()
  494.  
  495. if block and isLogName(block.name) then
  496. return true, block.name
  497. end
  498.  
  499. print("Sapling did not grow.")
  500. return false, nil
  501. end
  502.  
  503.  
  504. -- ------------------------------------------------------------
  505. -- PLANT SAPLING
  506. -- ------------------------------------------------------------
  507.  
  508. local function plantSapling(preferredName)
  509.  
  510. local slot = nil
  511.  
  512.  
  513. -- Try to use the same species.
  514. if preferredName then
  515. slot = findExactItem(preferredName)
  516. end
  517.  
  518.  
  519. -- Otherwise use whatever sapling is available.
  520. if not slot then
  521. slot = findAnySapling()
  522. end
  523.  
  524.  
  525. if not slot then
  526. print("WARNING: No saplings available!")
  527. return false
  528. end
  529.  
  530.  
  531. turtle.select(slot)
  532.  
  533. if turtle.place() then
  534. print("Sapling planted.")
  535. return true
  536. end
  537.  
  538.  
  539. print("WARNING: Unable to plant sapling.")
  540. return false
  541. end
  542.  
  543.  
  544. -- ------------------------------------------------------------
  545. -- HARVEST A SINGLE TREE
  546. --
  547. -- Turtle is standing one block NORTH (-Z) of the planting spot
  548. -- and facing SOUTH (+Z).
  549. -- ------------------------------------------------------------
  550.  
  551. local function processTree()
  552.  
  553. local block = blockInFront()
  554.  
  555. if not block then
  556. print("Planting spot is empty.")
  557.  
  558. plantSapling(nil)
  559.  
  560. return
  561. end
  562.  
  563.  
  564. local preferredSapling = nil
  565.  
  566.  
  567. -- --------------------------------------------------------
  568. -- SAPLING
  569. -- --------------------------------------------------------
  570.  
  571. if isSaplingName(block.name) then
  572.  
  573. print("Sapling detected: " .. block.name)
  574.  
  575. preferredSapling = block.name
  576.  
  577. local grown, logName = growSapling()
  578.  
  579. if not grown then
  580. print("Leaving sapling for next pass.")
  581. return
  582. end
  583.  
  584. block = blockInFront()
  585.  
  586. if not block then
  587. return
  588. end
  589. end
  590.  
  591.  
  592. -- --------------------------------------------------------
  593. -- TREE
  594. -- --------------------------------------------------------
  595.  
  596. if isLogName(block.name) then
  597.  
  598. print("Tree detected: " .. block.name)
  599.  
  600. if not preferredSapling then
  601. preferredSapling = saplingFromLog(block.name)
  602. end
  603.  
  604.  
  605. -- Remove base trunk.
  606. turtle.dig()
  607.  
  608.  
  609. -- Move into the space previously occupied by the trunk.
  610. if not turtle.forward() then
  611. print("ERROR: Could not enter trunk location.")
  612. return
  613. end
  614.  
  615.  
  616. -- Cut every connected log.
  617. harvestConnectedLogs()
  618.  
  619.  
  620. -- Return to our approach square.
  621. turtle.back()
  622.  
  623.  
  624. -- Plant replacement.
  625. plantSapling(preferredSapling)
  626.  
  627. print("Tree harvested.")
  628.  
  629. return
  630. end
  631.  
  632.  
  633. print("Not a tree or sapling: " .. block.name)
  634. end
  635.  
  636.  
  637. -- ------------------------------------------------------------
  638. -- DROP HARVEST INTO CHEST
  639. -- ------------------------------------------------------------
  640.  
  641. local function dumpHarvest()
  642.  
  643. goHome()
  644.  
  645. print("Dropping harvest into chest...")
  646.  
  647.  
  648. for slot = 1, 16 do
  649.  
  650. local item = turtle.getItemDetail(slot)
  651.  
  652. if item then
  653.  
  654. local keep =
  655. isBoneMealName(item.name) or
  656. isSaplingName(item.name) or
  657. isFuelName(item.name)
  658.  
  659.  
  660. if not keep then
  661. turtle.select(slot)
  662.  
  663. if not turtle.dropDown() then
  664. print("Chest may be full!")
  665. end
  666. end
  667. end
  668. end
  669.  
  670. end
  671.  
  672.  
  673. -- ------------------------------------------------------------
  674. -- VISIT ONE TREE
  675. -- ------------------------------------------------------------
  676.  
  677. local function visitTree(tree)
  678.  
  679. refuel()
  680.  
  681.  
  682. -- Stand one block north of the tree.
  683. local approachX = tree.x
  684. local approachZ = tree.z - 1
  685.  
  686.  
  687. moveTo(approachX, approachZ)
  688.  
  689.  
  690. -- Face south, toward the tree.
  691. face(0)
  692.  
  693.  
  694. print("")
  695. print("---------------------------")
  696. print("Tree " .. tree.x .. ", " .. tree.z)
  697. print("---------------------------")
  698.  
  699.  
  700. processTree()
  701.  
  702.  
  703. -- Deposit after EACH tree.
  704. dumpHarvest()
  705. end
  706.  
  707.  
  708. -- ------------------------------------------------------------
  709. -- MAIN PROGRAM
  710. -- ------------------------------------------------------------
  711.  
  712. print("")
  713. print("================================")
  714. print(" Six Tree Automatic Tree Farm")
  715. print("================================")
  716. print("")
  717. print("Home: " .. HOME_X .. ", " .. HOME_Z)
  718. print("Trees: " .. #trees)
  719. print("")
  720.  
  721.  
  722. refuel()
  723.  
  724.  
  725. while true do
  726.  
  727. print("")
  728. print("Beginning farm sweep...")
  729.  
  730. for i, tree in ipairs(trees) do
  731.  
  732. print("")
  733. print("Tree " .. i .. " of " .. #trees)
  734.  
  735. visitTree(tree)
  736. end
  737.  
  738.  
  739. goHome()
  740.  
  741. dumpHarvest()
  742.  
  743. print("")
  744. print("Sweep complete.")
  745. print("Sleeping " .. CHECK_INTERVAL .. " seconds.")
  746.  
  747. sleep(CHECK_INTERVAL)
  748. end
Advertisement