Advertisement
kimitsu_desu

Untitled

Jul 31st, 2014
225
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ------------------------------
  2. --- KIMITSU NO SHOUFU v0.3 ---
  3. ------------------------------
  4.  
  5. --- + To do / = To test / ? To consider
  6. --- = Switch to minecraft coordinates naming
  7. --- = Refueling
  8. --- = Replanting
  9. --- = Base unloading
  10. --- = In this version base should take priority!
  11. --- = Wandering
  12. --- = For that, "just stay low" special case
  13. --- = Obstacle hovering
  14. --- = Use current tree type to minimize checks
  15. --- = GPS calibration capability
  16. --- = Do not use dirt filters, just see if there is a block and if we can plant or not
  17. --- = Prevent filling free slots before main slots are full
  18. --- = x, y, z bounds
  19. --- + Forbid movement without calibration
  20. --- +
  21. --- + Check how fast .detect() is
  22. --- + Test modem ranges
  23. --- + Improve attacking
  24. --- + Pick the right time to suck
  25. --- + Sleep
  26. --- ? Turtle vs turtle avoidance system
  27. --- ? Test large red trees
  28. --- ? Test if general leaves are of the same type
  29. --- ? Refactor code to use single convention for addressing blocks and directions
  30. --- ? Refactor code to wrap stack search into movement or do something about it
  31.  
  32. ----------------
  33. --- Settings ---
  34.  
  35. local base = {x = 2290, y = 67, z = -866} --- Base coordinates
  36. local regions = { --- Rectangular regions the turtle should try to roam
  37.     {lt = {x = 2280, z = -887}, rb = {x = 2305, z = -865}},
  38.     {lt = {x = 2273, z = -885}, rb = {x = 2310, z = -870}},
  39.     {lt = {x = 2265, z = -880}, rb = {x = 2300, z = -860}},
  40.     {lt = {x = 2265, z = -875}, rb = {x = 2290, z = -852}}
  41. }
  42. local bounds = {lt = {x = 2200, y = 50, z = -900}, rb = {x = 2400, y = 100, z = -800}} --- Rectangular volume, the turtle will halt if it leaves its bounds
  43. local wood = {1, 2, 3, 4} --- Wood slots
  44. local leaves = {5, 6, 7, 8} --- Leaves slots
  45. local saplings = {9, 10, 11, 12} --- Sapling slots
  46. local dirt = {} --- Dirt slots. If left empty, dirt filters are off (slight speed improvement and more inventory space), but the turtle might try to plant saplings in invalid places.
  47. local fuel = 13 --- Fuel slot
  48. local freeSlots = {14, 15, 16} --- Free slots. For best results, these should be the last slots, and there should be no empty slots before them
  49.  
  50. local fuelLevel = 100 --- Minimum fuel level before refuel
  51. local fuelTreshold = 8 --- Minimum fuel item count before returning to base
  52. local saplingCount = 32 --- Number of saplings to keep in inventory
  53. local calibrationSleep = 5 --- Seconds to sleep before attempting to calibrate
  54.  
  55. -----------------------
  56. --- State variables ---
  57.  
  58. local self = {x = base.x, y = base.y, z = base.z} --- Coordinates
  59. local dx, dz = 1, 0 --- Heading
  60. local lastWood = false --- Last wood type checked by canChop
  61. local stack = {} --- List of blocks to chop down and scan for neighbors
  62. local replant = {} --- List of blocks to plant saplings below
  63.  
  64. --- Not saving ---
  65.  
  66. local target --- Target block to move to
  67. local hop = false --- Hopping over obstacle
  68.  
  69. -------------------------------------
  70. --- Other variables and constants ---
  71.  
  72. local comparator = {front = turtle.compare, up = turtle.compareUp, down = turtle.compareDown} --- Comparator function list for indexed access
  73. local region = {} --- Rectangle that includes all regions for random wandering
  74. local noDirt = (#dirt == 0) --- If true, try to plant saplings on anything
  75.  
  76. --------------------------------
  77. --- State saving and loading ---
  78.  
  79. function saveState()
  80.     local h = fs.open("kns.state", "w")
  81.     if not h then halt("saveState: Failed to open the file") end
  82.     h.writeLine(self.x)
  83.     h.writeLine(self.y)
  84.     h.writeLine(self.z)
  85.     h.writeLine(dx)
  86.     h.writeLine(dz)
  87.     h.writeLine(lastWood)
  88.     h.close()
  89. end
  90.  
  91. function saveStack()
  92.     local h = fs.open("kns.stack", "w")
  93.     if not h then halt("saveStack: Failed to open the file") end
  94.     for item = 1, #stack do
  95.         h.writeLine(stack[item].x)
  96.         h.writeLine(stack[item].y)
  97.         h.writeLine(stack[item].z)
  98.         h.writeLine(stack[item].visited == true)
  99.         h.writeLine(stack[item].wood or 0)
  100.     end
  101.     h.close()
  102. end
  103.  
  104. function saveReplant()
  105.     local h = fs.open("kns.replant", "w")
  106.     if not h then halt("saveReplant: Failed to open the file") end
  107.     for item = 1, #replant do
  108.         h.writeLine(replant[item].x)
  109.         h.writeLine(replant[item].y)
  110.         h.writeLine(replant[item].z)
  111.         h.writeLine(replant[item].wood)
  112.     end
  113.     h.close()
  114. end
  115.  
  116. --- Loading ---
  117.  
  118. function loadState()
  119.     local h = fs.open("kns.state", "r")
  120.     if h then
  121.         self.x = maybe(h.readLine())
  122.         self.y = maybe(h.readLine())
  123.         self.z = maybe(h.readLine())
  124.         dx = maybe(h.readLine())
  125.         dz = maybe(h.readLine())
  126.         lastWood = numberOrBoolean(h.readLine())
  127.         h.close()
  128.         loadStack()
  129.         loadReplant()
  130.     else
  131.         report("State file not found")
  132.         halt("Make sure the turtle is sitting at the base and is facing EAST")
  133.         saveState()
  134.         saveStack()
  135.         saveReplant()
  136.     end
  137. end
  138.  
  139. function loadStack()
  140.     local h = fs.open("kns.stack", "r")
  141.     if not h then halt("loadStack: Failed to open the file") end
  142.     local item = 0
  143.     repeat
  144.         item = item + 1
  145.         stack[item] = {}
  146.         stack[item].x = maybe(h.readLine())
  147.         stack[item].y = maybe(h.readLine())
  148.         stack[item].z = maybe(h.readLine())
  149.         stack[item].visited = (h.readLine() == "true")
  150.         stack[item].wood = maybe(h.readLine())
  151.     until not stack[item].x
  152.     stack[item] = nil
  153.     h.close()
  154. end
  155.  
  156. function loadReplant()
  157.     local h = fs.open("kns.replant", "r")
  158.     if not h then halt("loadReplant: Failed to open the file") end
  159.     local item = 0
  160.     repeat
  161.         item = item + 1
  162.         replant[item] = {}
  163.         replant[item].x = maybe(h.readLine())
  164.         replant[item].y = maybe(h.readLine())
  165.         replant[item].z = maybe(h.readLine())
  166.         replant[item].wood = maybe(h.readLine())
  167.     until not replant[item].x
  168.     replant[item] = nil
  169.     h.close()
  170. end
  171.  
  172. ---------------
  173. --- Utility ---
  174.  
  175. function maybe(str)
  176.     if str then return tonumber(str) else return nil end
  177. end
  178.  
  179. function numberOrBoolean(str)
  180.     if not str then
  181.         return false
  182.     elseif str == "false" then
  183.         return false
  184.     elseif str == "true" then
  185.         return true
  186.     else
  187.         return tonumber(str)
  188.     end
  189. end
  190.  
  191. function report(msg)
  192.     local stackSize = #stack
  193.     print("{" .. self.x .. "," .. self.y .. "," .. self.z .. ":" .. dx .. "," .. dz .. ":" .. stackSize .. "}" .. msg)
  194. end
  195.  
  196. function halt(msg)
  197.     report(msg .. " (Press enter...)")
  198.     read()
  199. end
  200.  
  201. -----------------------
  202. --- Turtle commands ---
  203.  
  204. function turnLeft()
  205.     while not turtle.turnLeft() do report("turnLeft: Failed") attack() end
  206.     dx, dz = dz, -dx
  207.     saveState()
  208. end
  209.  
  210. function turnRight()
  211.     while not turtle.turnRight() do report("turnRight: Failed") attack() end
  212.     dx, dz = -dz, dx
  213.     saveState()
  214. end
  215.  
  216. function stepForward()
  217.     while turtle.detect() and turtle.select(1) and not turtle.dig() do report("stepForward: Failed to dig or select slot 1") attack() end
  218.     while not turtle.forward() do report("stepForward: Failed to move") attack() end
  219.     self.x, self.z = self.x + dx, self.z + dz
  220.     saveState()
  221. end
  222.  
  223. function stepUp()
  224.     while turtle.detectUp() and turtle.select(1) and not turtle.digUp() do report("stepUp: Failed to dig or select slot 1") attackUp() end
  225.     while not turtle.up() do report("stepUp: Failed to move") attackUp() end
  226.     self.y = self.y + 1
  227.     saveState()
  228. end
  229.  
  230. function stepDown()
  231.     while turtle.detectDown() and turtle.select(1) and not turtle.digDown() do report("stepDown: Failed to dig or select slot 1") attackDown() end
  232.     while not turtle.down() do report("stepDown: Failed to move") attackDown() end
  233.     self.y = self.y - 1
  234.     saveState()
  235. end
  236.  
  237. function faceSide(block)
  238.     if (block.x == self.x) then
  239.         if (block.z ~= self.z) then
  240.             while ((block.z - self.z) * dz) <= 0 do
  241.                 if ((block.z - self.z) * dx) >= 0 then turnRight() else turnLeft() end
  242.             end
  243.         end
  244.     elseif (block.z == self.z) then
  245.         if (block.x ~= self.x) then
  246.             while ((block.x - self.x) * dx) <= 0 do
  247.                 if ((block.x - self.x) * dz) >= 0 then turnLeft() else turnRight() end
  248.             end
  249.         end
  250.     else
  251.         halt("faceSide: Not an adjacent block {" .. block.x .. "," .. block.y .. "," .. block.z .. "}")
  252.     end
  253. end
  254.  
  255. function faceBlock(block)
  256.     if math.abs(block.x - self.x) > math.abs(block.z - self.z) then
  257.         while dx ~= sign(block.x - self.x) do
  258.             if (dz * (block.x - self.x)) > 0 then turnLeft() else turnRight() end
  259.         end
  260.     elseif math.abs(block.z - self.z) > 0 then
  261.         while dz ~= sign(block.z - self.z) do
  262.             if (dx * (block.z - self.z)) > 0 then turnRight() else turnLeft() end
  263.         end
  264.     end
  265. end
  266.  
  267. function attack()
  268.     turtle.attack()
  269. end
  270.  
  271. function attackUp()
  272.     turtle.attackUp()
  273. end
  274.  
  275. function attackDown()
  276.     turtle.attackDown()
  277. end
  278.  
  279. ------------
  280. --- Math ---
  281.  
  282. function sign(value)
  283.     return ((value > 0 and 1) or (value < 0 and -1) or 0)
  284. end
  285.  
  286. -----------------------------------------
  287. --- Blocks and coordinates operations ---
  288.  
  289. function compareBlocks(a, b)
  290.     return ((a.x == b.x) and (a.y == b.y) and (a.z == b.z))
  291. end
  292.  
  293. function getUp(block)
  294.     return {x = block.x, y = block.y + 1, z = block.z}
  295. end
  296.  
  297. function getDown(block)
  298.     return {x = block.x, y = block.y - 1, z = block.z}
  299. end
  300.  
  301. function getFront(block)
  302.     return {x = block.x + dx, y = block.y, z = block.z + dz}
  303. end
  304.  
  305. function getBack(block)
  306.     return {x = block.x - dx, y = block.y, z = block.z - dz}
  307. end
  308.  
  309. function getRight(block)
  310.     return {x = block.x - dz, y = block.y, z = block.z + dx}
  311. end
  312.  
  313. function getLeft(block)
  314.     return {x = block.x + dz, y = block.y, z = block.z - dx}
  315. end
  316.  
  317. ------------------------
  318. --- Stack operations ---
  319.  
  320. function evalBlock(block)
  321.     return math.abs(block.x - self.x) + math.abs(block.y - self.y) + math.abs(block.z - self.z) +
  322.         (math.abs(sign(block.x - self.x) - dx) + math.abs(sign(block.z - self.z) - dz)) / 4
  323. end
  324.  
  325. function findBestBlock()
  326.     local best, bestEval
  327.     local itemEval
  328.     for item = 1, #stack do
  329.         if (not stack[item].visited) then
  330.             itemEval = evalBlock(stack[item])
  331.             if (best == nil) or (bestEval > itemEval) then
  332.                 best = item
  333.                 bestEval = itemEval
  334.             end
  335.         end
  336.     end
  337.     return best
  338. end
  339.  
  340. function findBlock(block)
  341.     for item = 1, #stack do
  342.         if compareBlocks(stack[item], block) then
  343.             return true
  344.         end
  345.     end
  346.     return false
  347. end
  348.  
  349. function pushStack(block)
  350.     block.wood = lastWood
  351.     stack[#stack + 1] = block
  352. end
  353.  
  354. --- Saplings ---
  355.  
  356. function findBestReplant()
  357.     local best, bestEval
  358.     local itemEval
  359.     for item = 1, #replant do
  360.         itemEval = evalBlock(replant[item])
  361.         if (best == nil) or (bestEval > itemEval) then
  362.             best = item
  363.             bestEval = itemEval
  364.         end
  365.     end
  366.     return best
  367. end
  368.  
  369. function pushReplant(block)
  370.     replant[#replant + 1] = {x = block.x, y = block.y + 1, z = block.z, wood = block.wood}
  371. end
  372.  
  373. function popReplant(block)
  374.     local found
  375.     repeat
  376.         found = false
  377.         for item = 1, #replant do
  378.             if compareBlocks(replant[item], block) then found = item break end
  379.         end
  380.         if found then table.remove(replant, found) end
  381.     until not found
  382. end
  383.  
  384. --- General ---
  385.  
  386. function clear(array)
  387.     local size = #array
  388.     for item = 1, size do
  389.         array[item] = nil
  390.     end
  391. end
  392.  
  393. ----------------------------
  394. --- Inventory operations ---
  395.  
  396. function compareSingle(direction, list, item)
  397.     if not turtle.select(list[item]) then halt("compare(" .. direction .. "): Failed to select slot " .. list[item]) end
  398.     if comparator[direction]() then return item end
  399.     return false
  400. end
  401.  
  402. function compare(direction, list)
  403.     for item = 1, #list do
  404.         if not turtle.select(list[item]) then halt("compare(" .. direction .. "): Failed to select slot " .. list[item]) end
  405.         if comparator[direction]() then return item end
  406.     end
  407.     return false
  408. end
  409.  
  410. ---------------------------
  411. --- Chopping operations ---
  412.  
  413. function canChop(direction)
  414.     if lastWood then
  415.         return compareSingle(direction, wood, lastWood) or compareSingle(direction, leaves, lastWood)
  416.     else
  417.         lastWood = compare(direction, wood)
  418.         return lastWood or compare(direction, leaves)
  419.     end
  420. end
  421.  
  422. function processStack()
  423.     if #stack == 0 then return false end
  424.     local item = findBestBlock()
  425.     if item then
  426.         if stack[item] ~= target then
  427.             target = stack[item]
  428.             report("Target: Block #" .. item .. " {" .. target.x .. "," .. target.y .. "," .. target.z .. "}")
  429.         end
  430.         if compareBlocks(target, self) then
  431.             if turtle.detectUp() and (not findBlock(getUp(self))) and canChop("up") then pushStack(getUp(self)) end
  432.             if turtle.detectDown() then
  433.                 if (not findBlock(getDown(self))) and canChop("down") then
  434.                     pushStack(getDown(self))
  435.                 elseif target.wood and (noDirt or compare("down", dirt)) then
  436.                     pushReplant(target)
  437.                     saveReplant()
  438.                 end
  439.             end
  440.             if turtle.detect() and (not findBlock(getFront(self))) and canChop("front") then pushStack(getFront(self)) end
  441.             --- Hopefully, efficient turning
  442.             local side = {
  443.                 block = getRight(self),
  444.                 turn = {
  445.                     block=getBack(self),
  446.                     turn = {block=getLeft(self)}
  447.                 },
  448.                 skip = {
  449.                     block = getLeft(self),
  450.                     turn = {block=getBack(self)}
  451.                 }
  452.             }
  453.             while side do
  454.                 if turtle.detect() and (not findBlock(side.block)) then
  455.                     faceSide(side.block)
  456.                     if canChop("front") then pushStack(side.block) end
  457.                     side = side.turn
  458.                 else
  459.                     side = side.skip or side.turn
  460.                 end
  461.             end
  462.             target.visited = true
  463.             saveStack()
  464.             target = nil
  465.         end
  466.         return true
  467.     else
  468.         lastWood = false
  469.         clear(stack)
  470.         saveStack()
  471.     end
  472.     return false
  473. end
  474.  
  475. ------------------
  476. --- Replanting ---
  477.  
  478. function processReplant()
  479.     if #replant == 0 then return false end
  480.     local item = findBestReplant()
  481.     if replant[item] ~= target then
  482.         target = replant[item]
  483.         report("Target: Replant #" .. item .. " {" .. target.x .. "," .. target.y .. "," .. target.z .. "}")
  484.     end
  485.     if compareBlocks(target, self) then
  486.         if not turtle.select(saplings[target.wood]) then halt("processReplant: Failed to select slot " .. saplings[target.wood]) end
  487.         if noDirt then
  488.             if not turtle.placeDown() then report("Failed to plant sapling here") end
  489.         else
  490.             while not turtle.placeDown() do report("processReplant: Failed to place down") attackDown() end
  491.         end
  492.         if turtle.getItemCount(saplings[target.wood]) < 2 then
  493.             halt("Universal entropy law violation: Saplings low")
  494.         end
  495.         popReplant(target)
  496.         saveReplant()
  497.         target = nil
  498.     end
  499.     return true
  500. end
  501.  
  502. --------------
  503. --- Moving ---
  504.  
  505. function move()
  506.     if (self.x < bounds.lt.x) or (self.y < bounds.lt.y) or (self.z < bounds.lt.z) or
  507.         (self.x > bounds.rb.x) or (self.y > bounds.rb.y) or (self.z > bounds.rb.z) then
  508.         halt("Emergency halt: moved out of bounds")
  509.     end
  510.     if not target then return false end
  511.     faceBlock(target)
  512.     if (self.x == target.x) and (self.z == target.z) then
  513.         if target.y then --- Target y is set: get to the desired altitude
  514.             if self.y > target.y then
  515.                 if turtle.detectDown() and (not findBlock(getDown(self))) and canChop("down") then pushStack(getDown(self)) saveStack() else stepDown() end
  516.             elseif self.y < target.y then
  517.                 if turtle.detectUp() and (not findBlock(getUp(self))) and canChop("up") then pushStack(getUp(self)) saveStack() else stepUp() end
  518.             else
  519.                 return false
  520.             end
  521.         else --- Target y is not set: just keep to the ground
  522.             if turtle.detectDown() then
  523.                 if (not findBlock(getDown(self))) and canChop("down") then
  524.                     pushStack(getDown(self))
  525.                     saveStack()
  526.                 else
  527.                     return false
  528.                 end
  529.             else
  530.                 stepDown()
  531.             end
  532.         end
  533.     else
  534.         if target.y then --- Target y is set: get as high as necessary and go
  535.             if self.y ~= math.max(self.y, target.y) then
  536.                 if turtle.detectUp() and (not findBlock(getUp(self))) and canChop("up") then pushStack(getUp(self)) saveStack() else stepUp() end
  537.             else
  538.                 if turtle.detect() then
  539.                     if not findBlock(getFront(self)) then
  540.                         if canChop("front") then
  541.                             pushStack(getFront(self))
  542.                             saveStack()
  543.                         elseif (not findBlock(getUp(self))) and canChop("up") then --- Unchoppable obstacle in front: try to hop over it
  544.                             pushStack(getUp(self))
  545.                             saveStack()
  546.                         else
  547.                             stepUp()
  548.                         end
  549.                     else
  550.                         stepForward()
  551.                     end
  552.                 else
  553.                     stepForward()
  554.                 end
  555.             end
  556.         else --- Target y is not set: keep to the ground, except when hopping over obstacles
  557.             if turtle.detectDown() or hop then
  558.                 hop = false
  559.                 if turtle.detect() then
  560.                     if not findBlock(getFront(self)) then
  561.                         if canChop("front") then
  562.                             pushStack(getFront(self))
  563.                             saveStack()
  564.                         elseif (not findBlock(getUp(self))) and canChop("up") then --- Unchoppable obstacle in front: try to hop over it
  565.                             pushStack(getUp(self))
  566.                             saveStack()
  567.                         else
  568.                             hop = true
  569.                             stepUp()
  570.                         end
  571.                     else
  572.                         stepForward()
  573.                     end
  574.                 else
  575.                     stepForward()
  576.                 end
  577.             else
  578.                 if turtle.detectDown() and (not findBlock(getDown(self))) and canChop("down") then pushStack(getDown(self)) saveStack() else stepDown() end
  579.             end
  580.         end
  581.     end
  582.     return true
  583. end
  584.  
  585. -------------------------------
  586. --- Refueling and unloading ---
  587.  
  588. function checkFuel()
  589.     while turtle.getFuelLevel() < fuelLevel do
  590.         report("Consuming fuel...")
  591.         if not turtle.select(fuel) then halt("checkFuel: Failed to select slot " .. fuel)
  592.         elseif not turtle.refuel(1) then halt("checkFuel: Failed to refuel") end
  593.         if (target ~= base) and (turtle.getItemCount(fuel) < fuelTreshold) then
  594.             report("Fuel low, returning to base...")
  595.             target = base
  596.             return true
  597.         end
  598.     end
  599.     return false
  600. end
  601.  
  602. function checkInventory()
  603.     --- Should return to base if any of the slots is filled up and all of the slots are occupied
  604.     local freeSlot =  false
  605.     local fullSlot = false
  606.     for slot = 1, 16 do
  607.         local count = turtle.getItemCount(slot)
  608.         if count == 0 then freeSlot = true break end
  609.         if count == 64 then fullSlot = true end
  610.     end
  611.     if fullSlot and not freeSlot then
  612.         report("Inventory full, returning to base...")
  613.         target = base
  614.         return true
  615.     end
  616.     return false
  617. end
  618.  
  619. function checkBase()
  620.     --- Suck up, supposedly, fuel from the chest below and then drop off all of the unnecessary items
  621.     if target ~= base then return false end
  622.     if compareBlocks(self, base) then
  623.         if not turtle.select(fuel) then halt("checkBase: Failed to select slot " .. fuel) end
  624.         if not turtle.suckDown() then report("checkBase: Failed to suck fuel") end
  625.         for item = 1, #wood do
  626.             if not turtle.select(wood[item]) then halt("checkBase: Failed to select slot " .. wood[item]) end
  627.             local count = turtle.getItemCount(wood[item])
  628.             if count > 1 then
  629.                 if not turtle.dropDown(count - 1) then report("checkBase: Failed to drop wood") end
  630.             end
  631.         end
  632.         for item = 1, #saplings do
  633.             if not turtle.select(saplings[item]) then halt("checkBase: Failed to select slot " .. saplings[item]) end
  634.             local count = turtle.getItemCount(saplings[item])
  635.             if count > saplingCount then
  636.                 if not turtle.dropDown(count - saplingCount) then report("checkBase: Failed to drop saplings") end
  637.             end
  638.         end
  639.         for item = 1, #freeSlots do
  640.             if not turtle.select(freeSlots[item]) then halt("checkBase: Failed to select slot " .. freeSlots[item]) end
  641.             local count = turtle.getItemCount(freeSlots[item])
  642.             if count > 0 then
  643.                 if not turtle.dropDown(count) then report("checkBase: Failed to drop loot") end
  644.             end
  645.         end
  646.         target = nil
  647.     end
  648.     return true
  649. end
  650.  
  651. -----------------
  652. --- Wandering ---
  653.  
  654.     function wander()
  655.     --- Assumption is that we are at the target (otherwise move would return true)
  656.     --- And that target originates from this function (correct main loop order should guarantee that)
  657.     --- So, no matter what the target is, we reset it
  658.     local found
  659.     repeat
  660.         target = {x = region.lt.x + math.random(region.rb.x - region.lt.x + 1) - 1, y = false, z = region.lt.z + math.random(region.rb.z - region.lt.z + 1) - 1}
  661.         found = false
  662.         for item = 1, #regions do
  663.             if (target.x >= regions[item].lt.x) and (target.x <= regions[item].rb.x) and
  664.                 (target.z >= regions[item].lt.z) and (target.z <= regions[item].rb.z) then
  665.                 found = true
  666.                 break
  667.             end
  668.         end
  669.     until found
  670.     report("Target: Random {" .. target.x .. ",---," .. target.z .. "}")
  671.     return true
  672. end
  673.  
  674. function checkTarget()
  675.     --- Drop the random wandering target if any of the important stuff needs to be done
  676.     if target and (not target.y) and ((#stack > 0) or (#replant > 0)) then
  677.         target = nil
  678.     end
  679.     return false
  680. end
  681.  
  682. ------------------------------
  683. --- Various initialization ---
  684.  
  685. function init()
  686.     for item = 1, #regions do
  687.         local current = {
  688.             lt = {x = math.min(regions[item].lt.x, regions[item].rb.x), z = math.min(regions[item].lt.z, regions[item].rb.z)},
  689.             rb = {x = math.max(regions[item].lt.x, regions[item].rb.x), z = math.max(regions[item].lt.z, regions[item].rb.z)}
  690.         }
  691.         if not region.lt then region.lt = {x = current.lt.x, z = current.lt.z} end
  692.         if region.lt.x > current.lt.x then region.lt.x = current.lt.x end
  693.         if region.lt.z > current.lt.z then region.lt.z = current.lt.z end
  694.         if not region.rb then region.rb = {x = current.rb.x, z = current.rb.z} end
  695.         if region.rb.x < current.rb.x then region.rb.x = current.rb.x end
  696.         if region.rb.z < current.rb.z then region.rb.z = current.rb.z end
  697.     end
  698. end
  699.  
  700. function calibrate()
  701.     report("Attempting to calibrate...")
  702.     sleep(calibrationSleep)
  703.     local tx, ty, tz = gps.locate(calibrationSleep)
  704.     if tx then
  705.         self = {x = tx, y = ty, z = tz}
  706.         saveState()
  707.         report("Coordinates calibrated")
  708.         local attempt = 0
  709.         local nx, ny, nz
  710.         repeat
  711.             if turtle.detect() then
  712.                 attempt = attempt + 1
  713.                 if (attempt % 5) == 0 then
  714.                     if turtle.up() then
  715.                         self.y = self.y + 1
  716.                     else
  717.                         report("Heading calibration failed")
  718.                         return false
  719.                     end
  720.                 else
  721.                     if turtle.turnRight() then
  722.                         dx, dz = -dz, dx
  723.                         saveState()
  724.                     else
  725.                         report("Heading calibration failed")
  726.                         return false
  727.                     end
  728.                 end
  729.             else
  730.                 if turtle.forward() then
  731.                     self.x = self.x + dx
  732.                     self.z = self.z + dz
  733.                     saveState()
  734.                 else
  735.                     report("Heading calibration failed")
  736.                     return false
  737.                 end
  738.             end
  739.             nx, ny, nz = gps.locate(calibrationSleep)
  740.             if not nx then
  741.                 report("Heading calibration failed")
  742.                 return false
  743.             end
  744.             if attempt > 100 then
  745.                 report("Heading calibration failed")
  746.                 return false
  747.             end
  748.         until (nx ~= tx) or (nz ~= tz)
  749.         self = {x = nx, y = ny, z = nz}
  750.         dx = nx - tx
  751.         dz = nz - tz
  752.         saveState()
  753.         report("Heading calibrated")
  754.         return true
  755.     else
  756.         report("Calibration failed")
  757.         return false
  758.     end
  759. end
  760.  
  761. -----------------
  762. --- Main loop ---
  763.  
  764. print("------------------------------")
  765. print("--- Kimitsu no Shoufu v0.3 ---")
  766. print("------------------------------")
  767.  
  768. init()
  769. loadState()
  770. checkFuel()
  771. while not calibrate() do sleep(0) end
  772.  
  773. report("Main loop activated")
  774.  
  775. while
  776.     checkTarget() or
  777.     move() or
  778.     checkBase() or
  779.     checkFuel() or
  780.     checkInventory() or
  781.     processStack() or
  782.     processSaplings() or
  783.     wander()
  784. do sleep (0) end
  785.  
  786. report("Main loop terminated")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement