Vaerys_Dawn

new_turtle_base

Feb 9th, 2021
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.22 KB | None | 0 0
  1. -- home is a world location
  2. home = {x = nil, y = nil, z = nil, rotation = nil}
  3.  
  4. -- work is relative to home
  5. work = {x = nil, y = nil, z = nil, rotation = nil}
  6.  
  7. -- location is relative to home
  8. location = {x = nil, y = nil, z = nil, rotation = nil}
  9.  
  10. listeners = {}
  11.  
  12. validTools = {crafting = "Crafting", pickaxe = "Pickaxe", axe = "Axe", shovel = "Shovel", hoe = "Hoe", modem = "Modem", none = "None"}
  13. tools = {left = validTools.none, right = validTools.none}
  14.  
  15. fuel = { "minecraft:coal", "minecraft:charcoal" }
  16.  
  17. -- initialises the co-ordinates system and links up rednet
  18. function init()
  19.   local x, y, z, rotation, startRotation = getInitialPosition()
  20.   initHome(x, y, z).
  21.   location.x = home.x - x
  22.   location.y = home.y - y
  23.   location.z = home.z - z
  24.   location.rotation = rotation
  25.   initWork()
  26.   rotateTo(startRotation)
  27. end
  28.  
  29. -- returns current x, y, z position of the turtle as well as the current rotation
  30. function getInitialPosition()
  31.   local x1, y1, z1 = gps.locate()
  32.   local rotation = 0
  33.   local worldRotation = nil
  34.   local foundRotation = false
  35.  
  36.   -- attempt to move turtle to find the facing location of the turtle
  37.   while not foundRotation and rotation < 4 do
  38.     moved = turtle.forward()
  39.     local x2, y2, z2 = gps.locate()
  40.     if moved then
  41.       if z2 > z1 then worldRotation = 0
  42.       elseif x2 > x1 then worldRotation = 1
  43.       elseif z2 < z1 then worldRotation = 2
  44.       elseif x2 < x1 then worldRotation = 3 end
  45.       foundRotation = true
  46.       -- return location back to start
  47.       turtle.turnLeft()
  48.       turtle.turnLeft()
  49.       turtle.forward()
  50.     else
  51.       -- rotate clockwise
  52.       turtle.turnRight()
  53.       rotation = rotation + 1
  54.     end
  55.   end
  56.  
  57.   -- error out if rotation could not be found
  58.   if not foundRotation then
  59.     sendStatus("Could not find rotation")
  60.     error()
  61.   end
  62.  
  63.   local startWorldRotation = (worldRotation - rotation - 2) % 4
  64.   home.rotation = settings.get("HomeRotation", startWorldRotation)
  65.   local startRotation = (home.rotation - startWorldRotation) % 4
  66.   local currentRotation = (home.rotation - worldRotation) % 4
  67.   return x1, y1, z1, currentRotation, startRotation
  68. end
  69.  
  70. -- collects existing home location or creates home location
  71. function initHome(x, y, z, dir)
  72.   settings.load("settings")
  73.   home.x = settings.get("HomeXPos", x)
  74.   home.y = settings.get("HomeYPos", y)
  75.   home.z = settings.get("HomeZPos", z)
  76.   saveHome()
  77. end
  78.  
  79. -- saves home location to settings
  80. function saveHome()
  81.   settings.load("settings")
  82.   settings.set("HomeXPos", home.x)
  83.   settings.set("HomeYPos", home.y)
  84.   settings.set("HomeZPos", home.z)
  85.   settings.set("HomeRotation", home.rotation)
  86.   settings.save("settings")
  87. end
  88.  
  89. -- sends a gps request to get current work location, uses home rotation to infer correct rotation
  90. function initWorkLocation()
  91.   settings.load("settings")
  92.   work.x = settings.get("WorkXPos", location.x)
  93.   work.y = settings.get("WorkYPos", location.y)
  94.   work.z = settings.get("WorkZPos", location.z)
  95.   work.rotation = settings.get("WorkRotation", location.rotation)
  96.   saveWork()
  97. end
  98.  
  99. -- saves work location to settings
  100. function saveWork()
  101.   settings.load("settings")
  102.   settings.set("WorkXPos", work.x)
  103.   settings.set("WorkYPos", work.y)
  104.   settings.set("WorkZPos", work.z)
  105.   settings.set("WorkRotation", work.rotation)
  106.   settings.save("settings")
  107. end
  108.  
  109. -- moves position using co-ordinates relatove to home
  110. function moveToPosition(newX, newY, newZ, newRot, locationName)
  111.   if not locationName then locationName = "Somewhere" end
  112.   local newLocation = {x = newX, y = newY, z = newZ, rotation = newRot}
  113.   local blockages = 0
  114.   while not compareLocations(location, newLocation) and blockages < 10 do
  115.     -- move to new y location
  116.     while location.y ~= newLocation.y do
  117.       if location.y > newLocation.y then
  118.         sendStatus("Moving Down towards ".. locationName)
  119.         moved = moveDown()
  120.       elseif location.y < newLocation.y then
  121.         sendStatus("Moving Up towards ".. locationName)
  122.         moved = moveUp()
  123.       end
  124.       if not moved then
  125.         blockages = blockages + 1
  126.         break
  127.       end
  128.     end
  129.     -- move to new x location
  130.     while location.x ~= newLocation.x do
  131.       if location.x > newLocation.x then
  132.         sendStatus("Moving Left towards ".. locationName)
  133.         if location.rotation ~= 3 then rotateTo(3) end
  134.         moved = moveForward()
  135.       elseif location.x < newLocation.x then
  136.         sendStatus("Moving Right towards ".. locationName)
  137.         if location.rotation ~= 1 then rotateTo(1) end
  138.         moved = moveForward()
  139.       end
  140.       if not moved then
  141.         blockages = blockages + 1
  142.         break
  143.       end
  144.     end
  145.     -- move to new z location
  146.     while location.z ~= newLocation.z do
  147.       if location.z > newLocation.z then
  148.         sendStatus("Moving Backwards towards ".. locationName)
  149.         if location.rotation ~= 2 then rotateTo(2) end
  150.         moved = moveForward()
  151.       elseif location.z < newLocation.z then
  152.         sendStatus("Moving Forwards towards ".. locationName)
  153.         if location.rotation ~= 0 then rotateTo(0) end
  154.         moved = moveForward()
  155.       end
  156.       if not moved then
  157.         blockages = blockages + 1
  158.         break
  159.       end
  160.     end
  161.   end
  162.   rotateTo(newDir)
  163.   return compareLocations(location, newLocation, true)
  164. end
  165.  
  166. -- moves position using gps and world co-ordinates
  167. function moveToWorldPosition()
  168.  
  169. end
  170.  
  171. -- rotates the turtle once to the left and updates it's rotation
  172. function rotateLeft()
  173.   location.rotation = location.rotation-1
  174.   if (location.rotation == -1) then
  175.     location.rotation = 3
  176.   end
  177.   turtle.turnLeft()
  178. end
  179.  
  180. -- rotates the turtle once to the right and updates it's rotation
  181. function rotateRight()
  182.   location.rotation = location.rotation+1
  183.   if (location.rotation == 4) then
  184.     location.rotation = 0
  185.   end
  186.   turtle.turnRight()
  187. end
  188.  
  189. -- rotates the turtle to a new rotation based on home relative rotation
  190. function rotateTo(newDir)
  191.   if location.rotation == newDir then
  192.     return
  193.   elseif (location.rotation + 1) % 4 == newDir then
  194.     rotateRight()
  195.   elseif (location.rotation - 1) % 4 == newDir then
  196.     rotateLeft()
  197.   else
  198.     while location.rotation ~= newDir do
  199.       rotateLeft()
  200.     end
  201.   end
  202. end
  203.  
  204. -- rotates the turtle to face a world rotation
  205. function rotateToGlobal(newDir)
  206.  
  207. end
  208.  
  209. -- moves the turtle forward and updates the location based on relative rotation
  210. -- returns true on successful movement
  211. function moveForward()
  212.  
  213. end
  214.  
  215. -- moves the turtle up one block and updates the location
  216. -- returns true on successful movement
  217. function moveUp()
  218.   if canDig() then
  219.     while turtle.detectUp() do
  220.       turtle.digUp()
  221.     end
  222.   end
  223.   local moved = turtle.up()
  224.   if not moved then return false end
  225.   location.y = location.y + 1
  226.   return true
  227. end
  228.  
  229. -- moves the turtle down one block and updates the location
  230. -- returns true on successful movement
  231. function moveDown()
  232.   if canDig() then
  233.     while turtle.detectDown() do
  234.       turtle.digDown()
  235.     end
  236.   end
  237.   local moved = turtle.down()
  238.   if not moved then return false end
  239.   location.y = location.y - 1
  240.   return true
  241. end
  242.  
  243. -- returns the turtle's current world position
  244. function currentWorldPosition()
  245.   local x, y, z = gps.locate()
  246.   local rotation = getWorldRotation()
  247.   return "[".. x..", ".. y..", ".. z..", ".. rotation .."]"
  248. end
  249.  
  250. -- returns the turtle's current relative position
  251. function currentPosition()
  252.   local x = location.x
  253.   local x = location.y
  254.   local x = location.z
  255.   local x = location.rotation
  256.   return "[".. x..", ".. y..", ".. z..", ".. rotation .."]"
  257. end
  258.  
  259. function compareLocations(tab1, tab2, includeRotation)
  260.   if includeRotation then
  261.     return tab1.x == tab2.x and tab1.y == tab2.y and tab1.z == tab2.z and tab1.rotation == tab2.rotation
  262.   else
  263.     return tab1.x == tab2.x and tab1.y == tab2.y and tab1.z == tab2.z
  264.   end
  265. end
  266.  
  267. -- returns list of valid tools
  268. function getValidToolText()
  269.   local text = ""
  270.   for k, v in pairs(validTools) do
  271.     if text ~= "" then text = text.. ", " end
  272.     text = text .. v
  273.   end
  274.   return text
  275. end
  276.  
  277. -- asks the player to input in the currently equipped tools on the turtle
  278. function getTools()
  279.   local complete = false
  280.   local toolText = "Valid Tools: ".. getValidToolText()
  281.   local sides = peripheral.getNames()
  282.   if tableContains("left", sides) then
  283.     complete = true
  284.     tools.left = validTools.modem
  285.   end
  286.   while not complete do
  287.     term.clear()
  288.     term.setCursorPos(1,1)
  289.     print(toolText)
  290.     io.write("Enter Left Tool: ")
  291.     local leftTool = io.read()
  292.     local valid, leftTool = validTool(leftTool)
  293.     if valid then
  294.       complete = true
  295.       tools.left = leftTool
  296.     end
  297.   end
  298.   complete = false
  299.   if tableContains("right", sides) then
  300.     complete = true
  301.     tools.right = validTools.modem
  302.   end
  303.   while not complete do
  304.     term.clear()
  305.     term.setCursorPos(1,1)
  306.     print(toolText)
  307.     io.write("Enter Right Tool: ")
  308.     local rightTool = io.read()
  309.     local valid, rightTool = validTool(rightTool)
  310.     if valid then
  311.       complete = true
  312.       tools.right = rightTool
  313.     end
  314.   end
  315. end
  316.  
  317. -- returns true if tool is a tool found in the valid tools list
  318. function validTool(tool)
  319.   for k,v in pairs(validTools) do
  320.     if string.lower(v) == string.lower(tool) then
  321.       return true, v
  322.     end
  323.   end
  324.   return false, validTools.none
  325. end
  326.  
  327. -- returns true if table contains str
  328. function tableContains(str, table)
  329.   for k, v in pairs(table) do
  330.     if v == str then return true end
  331.   end
  332.   return false
  333. end
  334.  
  335. -- resets the turtles working settings
  336. function resetSettings()
  337.   settings.load("settings")
  338.   settings.clear()
  339.   settings.save("settings")
  340. end
  341.  
  342. -- finds an item in the turtle's inventory based off supplied id and returns as a list of inventory slots
  343. function findItem(id)
  344.   local itemTable = {}
  345.   for i = 1, 16, 1 do
  346.     local slotData = turtle.getItemDetail(i)
  347.     if (slotData and slotData.name == id) then
  348.       table.insert(itemTable, i)
  349.     end
  350.   end
  351.   if table.getn(itemTable) > 0 then
  352.     return itemTable
  353.   end
  354.   return nil
  355. end
  356.  
  357. -- returns true if empty slot was found and item was moved
  358. function moveItemToEmpty(slot)
  359.   turtle.select(slot)
  360.   for i = 1, 16, 1 do
  361.     if i ~= slot then
  362.       if turtle.transferTo(i) then
  363.         return true
  364.       end
  365.     end
  366.   end
  367.   return false
  368. end
  369.  
  370. -- returns true if space remains
  371. function checkSpace()
  372.   for i = 1, 16, 1 do
  373.     if not turtle.getItemDetail(i) then
  374.       return true
  375.     end
  376.   end
  377.   return false
  378. end
  379.  
  380. -- attempts to merge stacks of all items starting from the bottom moving to the top most slot
  381. function minifyStacks()
  382.   for i = 16, 1, -1 do
  383.     local slotData = turtle.getItemDetail(i)
  384.     if slotData then
  385.       slotsTable = findItem(slotData.name)
  386.       if slotsTable and table.getn(slotsTable) > 1 then
  387.         for k,v in pairs(slotsTable or {}) do
  388.           turtle.select(v)
  389.           turtle.transferTo(i, turtle.getItemSpace(i))
  390.         end
  391.       end
  392.     end
  393.   end
  394. end
  395.  
  396. -- returns home and requests more fuel
  397. function giveMeFuel()
  398.   while not hasFuel() do
  399.     sleep(2)
  400.   end
  401.   returnToWork()
  402. end
  403.  
  404. -- attempts to fill fuel slot, returns true if enough fuel is located in the fuel slot.
  405. function hasFuel()
  406.   local fuelSlots = {}
  407.  
  408.   local slotData = turtle.getItemDetail(1)
  409.   -- search the first slot for a valid fuel item
  410.   for k,v in pairs(fuel or {}) do
  411.     -- find if any other slots contain any fuel
  412.     local slotTable = findItem(v)
  413.     table.insert(fuelSlots, slotTable)
  414.  
  415.     -- look in slot one, if contains fuel return
  416.     if (slotData and slotData.name == v) then
  417.       return turtle.getItemCount(1) > 1, slotTable
  418.     end
  419.   end
  420.  
  421.   -- move item out of fuel slot
  422.   if slotData then
  423.     moveItemToEmpty(1)
  424.   end
  425.  
  426.   -- move valid fuel into slot
  427.   for k,v in pairs(fuelSlots or {}) do
  428.     if v then
  429.       if table.getn(v) > 0 then
  430.         turtle.select(v[1])
  431.         turtle.transferTo(1)
  432.       end
  433.       return turtle.getItemCount(1) > 1, v
  434.     end
  435.   end
  436.   return false, nil
  437. end
  438.  
  439. -- returns true if item is a valid source of fuel
  440. function isFuel(slotData)
  441.   for k,v in pairs(fuel or {}) do
  442.     if slotData.name == v then return true end
  443.   end
  444.   return false
  445. end
  446.  
  447. -- attempts to find the minimum fuel level required to return home safely
  448. function getMinFuelLevel()
  449.   if locationNil(work) or locationNil(home) then return 800 end
  450.   return math.abs(work.x) + math.abs(work.z) + math.abs(home.y - work.y) + 50
  451. end
  452.  
  453. -- checks fuel levels and attempts to refuel the turtle
  454. function refuel()
  455.   local hasFuelLeft, fuelSlots = hasFuel()
  456.   if turtle.getFuelLevel() < getMinFuelLevel() then
  457.     if not hasFuelLeft then
  458.       giveMeFuel()
  459.     end
  460.   end
  461.  
  462.   if turtle.getFuelLevel() < 5120 then
  463.     turtle.select(1)
  464.     coalCount = turtle.getItemCount(1)
  465.     if coalCount > 0 then turtle.refuel(coalCount-1) end
  466.   end
  467. end
  468.  
  469. -- drops any extra stacks of items found in the turtle's inventory, maintaining only one stack of the given item
  470. function dumpExtraStacks(itemId)
  471.   items = findItem(itemId)
  472.   if items and #items > 1 then
  473.     for i = 2, #items, 1 do
  474.       turtle.select(items[i])
  475.       turtle.drop()
  476.     end
  477.   end
  478. end
  479.  
  480. -- sends a rednet message to find listening computers to send further status updates to
  481. function getListeners()
  482.   listeners = {rednet.lookup("turtle_status")}
  483.   if listeners then
  484.     for k, v in pairs(listeners) do
  485.       rednet.send(v, "request_connect")
  486.     end
  487.   end
  488. end
  489.  
  490. -- opens up the turtle's rednet system
  491. function openRednet()
  492.   side = getModemSide()
  493.   if not side then error("could not find modem") end
  494.   rednet.open(side, 255)
  495. end
  496.  
  497. -- returns the side of the turtle the modem is on else it returns nil if no modem is found
  498. function getModemSide()
  499.   sides = peripheral.getNames()
  500.   for k, v in pairs(sides) do
  501.     if peripheral.getType(v) == "modem" then return v end
  502.   end
  503.   return nil
  504. end
  505.  
  506. -- initialises the turtle's rednet system
  507. function initRednet()
  508.   term.clear()
  509.   term.setCursorPos(1,1)
  510.   print("Initialising Rednet System")
  511.   openRednet()
  512.   getListeners()
  513. end
  514.  
  515. -- sends a status update to all connected computers registered to listen for status updates
  516. function sendStatus(status)
  517.   for k, v in pairs(listeners) do
  518.     rednet.send(v, status.. "\n" .. currentWorldPosition())
  519.   end
  520. end
  521.  
Add Comment
Please, Sign In to add comment