Advertisement
Nezn

Rednet Turtle Forester (комментарии) [CC]

Jul 12th, 2015
424
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.53 KB | None | 0 0
  1. --Установка переменных
  2. args = { ... } --аргументы
  3. thisType = 0 --тип компьютера
  4. workerID = 0 --айди черепашки-дровосека
  5. helperID = 0 --айди черепашки-помощника
  6. serverID = 0 --айди сервера
  7. x, y, d = 0, 0, 0 --размеры поля с деревьями
  8. sapling = false --дополнительная переменная, если на пути саженец
  9. protocol = "TurtleFProto" --название протокола
  10. timer = 0 --переменная таймера для зацикливания работы
  11. refuel = false --переменная с состоянием зарядки
  12. delay = 600 --задержка между работой черепашки
  13. working = false --переменная с состоянием зацикливания
  14.  
  15. --Рисует линию текста (GUI)
  16. function line(y, backcolor, text)
  17.         term.setCursorPos(1, y)
  18.         term.setBackgroundColor(backcolor)
  19.         term.clearLine()
  20.         term.write(text)
  21. end
  22.  
  23. --Поиск модема
  24. function findModem()
  25.         sides = {"front","back","left","right","top","bottom"}
  26.         for i=1,6 do
  27.                 if peripheral.getType(sides[i]) == "modem" then
  28.                         rednet.open(sides[i])
  29.                         return
  30.                 end
  31.         end
  32.         print("Need wireless modem!") --сообщение о том, что модем не найден
  33.         error(r)
  34. end
  35.  
  36. --Получает должность компьютера
  37. function getName()
  38.     if thisType == 1 then
  39.         workerID = os.getComputerID()
  40.         return "worker"
  41.     elseif thisType == 2 then
  42.         serverID = os.getComputerID()
  43.         return "server"
  44.     elseif thisType == 3 then
  45.         helperID = os.getComputerID()
  46.         return "helper"
  47.     end
  48. end
  49.  
  50. --Поиск других компьютеров
  51. function findFriends()
  52.     rednet.broadcast("zdarova_ya_"..getName(), protocol) --приветствие
  53.     while true do
  54.             local event, sender, msg, prot = os.pullEvent("rednet_message")
  55.             if prot == protocol then
  56.             if string.find(msg, "zdarova") then --ответ
  57.                 rednet.send(sender, "privet_ya_"..getName(), protocol)
  58.             end
  59.             if string.find(msg, "ya_server") and thisType ~= 2 then --тут идет разбор ответившего клиента
  60.                 serverID = sender
  61.                 print("Server ID: "..serverID)
  62.             elseif string.find(msg, "ya_worker") and thisType ~= 1 then
  63.                 workerID = sender
  64.                 print("Worker ID: "..workerID)
  65.             elseif string.find(msg, "ya_helper") and thisType ~= 3 then
  66.                 helperID = sender
  67.                 print("Helper ID: "..helperID)
  68.             end
  69.             if serverID ~= 0 and workerID ~= 0 and helperID ~= 0 then --настройка монитора (GUI)
  70.                 if thisType == 2 then
  71.                     print("Look at the monitor! Program has been started.")
  72.                         term.redirect(monitor)
  73.                         monitor.setTextScale(1)
  74.                     line(1, colors.black, "  RTF")
  75.                         line(2, colors.green, "FUEL")
  76.                         line(3, colors.green, "SAPLING")
  77.                         line(4, colors.gray, "START")
  78.                         line(5, colors.gray, "EXIT")
  79.                 end
  80.                 return
  81.             end
  82.         end
  83.     end
  84. end
  85.  
  86. --Анализ аргументов
  87. function checkArgs()
  88.     if args[1] == nil then
  89.         print("Need args!") --если вообще нет
  90.         error(r)
  91.     else
  92.         thisType = tonumber(args[1]) --аргумент типа
  93.     end
  94.     if args[4] == nil and thisType == 1 then --проверка наличия размеров поля
  95.         print("Need args!")
  96.         error(r)
  97.     elseif thisType == 1 then --если есть, присваивание
  98.         x, y, d = tonumber(args[2]), tonumber(args[3]), tonumber(args[4])
  99.         if args[5] ~= nil then --проверка протокола
  100.             protocol = args[5]
  101.         end
  102.     elseif thisType == 2 and args[2] ~= nil then --если сервер, то проверяется задержка и протокол
  103.         delay = tonumber(args[2])
  104.         if args[3] ~= nil then
  105.             protocol = args[3]
  106.         end
  107.     elseif thisType == 3 and args[2] ~= nil then --если помощник, то только протокол
  108.         protocol = args[2]
  109.     end
  110. end
  111.  
  112. --Перемещение черепашки
  113. function move(w)
  114.     turtle.suck() --забирание дропа
  115.     if turtle.getFuelLevel() == 0 then --заправка
  116.         turtle.refuel(1)
  117.     end
  118.     if w == "forward" then --тут скриптик, чтобы мобы или случайные блоки на пути не сбивали
  119.         while true do
  120.             local res = turtle.forward()
  121.             if res then
  122.                 break
  123.             else
  124.                 turtle.dig()
  125.                 turtle.select(16)
  126.                 turtle.equipLeft()
  127.                 turtle.attack()
  128.                 turtle.equipLeft()
  129.                 turtle.select(1)
  130.                 findModem()
  131.                 sleep(1)
  132.             end
  133.         end
  134.     elseif w == "up" then --вверх
  135.         turtle.up()
  136.     elseif w == "down" then --вниз
  137.         turtle.down()
  138.     end
  139. end
  140.  
  141. --Поиск монитора
  142. function findMonitor()
  143.         local e = peripheral.getNames() --перебор периферии
  144.         for i=1,#e do
  145.                 if peripheral.getType(e[i]) == "monitor" then
  146.                         local m = peripheral.wrap(e[i])
  147.                         if m.isColor() then
  148.                 monitor = m
  149.                                 return
  150.                         end
  151.                 end
  152.         end
  153.         if monitor == nil then
  154.                 print("Need advanced monitor!") --сообщение об ошибке
  155.                 error(r)
  156.         end
  157. end
  158.  
  159. --Выгрузка вещей после работы
  160. function dropItems()
  161.     checkSapling()
  162.     for i=1,15 do
  163.         if turtle.getItemCount(i) > 0 then
  164.             local d = turtle.getItemDetail(i) --в сундук выгружаются только яблоко и бревна
  165.             turtle.select(i)
  166.             if d.name == "minecraft:log" or d.name == "minecraft:apple" then
  167.                 turtle.dropDown()
  168.             elseif d.name ~= "minecraft:coal" and d.name ~= "minecraft:sapling" then
  169.                 turtle.dropUp()
  170.             end
  171.         end
  172.     end
  173.     turtle.select(1)
  174. end
  175.  
  176. --Функция для складывания ростков в один слот
  177. function checkSapling()
  178.     for i=1,15 do
  179.         if turtle.getItemCount(i) > 0 then
  180.             local d = turtle.getItemDetail(i)
  181.             if d.name == "minecraft:sapling" then
  182.                 turtle.select(i)
  183.                 if turtle.getItemCount(2) < 64 then
  184.                     turtle.transferTo(2, turtle.getItemSpace(2))
  185.                 end
  186.                 if turtle.getItemCount(i) > 0 then
  187.                     return
  188.                 end
  189.             end
  190.         end
  191.     end
  192. end
  193.  
  194. --Функция движения для черепашки-дровосека
  195. --Здесь идет поход по полю, срубание деревьев и рассадка саженцев
  196. function work()
  197.     for i=1,x do
  198.         for j=1,y do
  199.             if sapling then
  200.                 for k=1,d-1 do
  201.                     move("forward")
  202.                 end
  203.                 sapling = false
  204.             else
  205.                 for k=1,d+1 do
  206.                     move("forward")
  207.                 end
  208.             end
  209.             local a, b = turtle.inspect()
  210.             while b.name == "minecraft:log" do
  211.                 turtle.dig()
  212.                 if turtle.inspectUp() then
  213.                     turtle.digUp()
  214.                 end
  215.                 move("up")
  216.                 a, b = turtle.inspect()
  217.             end
  218.             while not turtle.inspectDown() do
  219.                                 move("down")
  220.                         end
  221.             if not turtle.inspect() then
  222.                 turtle.select(2)
  223.                 turtle.place()
  224.                 turtle.select(1)
  225.             end
  226.             local a, b = turtle.inspect()
  227.             if b.name == "minecraft:sapling" then
  228.                 turtle.turnLeft()
  229.                 move("forward")
  230.                 turtle.turnRight()
  231.                 move("forward")
  232.                 move("forward")
  233.                 turtle.turnRight()
  234.                 move("forward")
  235.                 turtle.turnLeft()
  236.                 sapling = true
  237.             end
  238.         end
  239.         if sapling then
  240.             for k=1,d+1 do
  241.                 move("forward")
  242.             end
  243.             sapling = false
  244.         else
  245.             for k=1,d+3 do
  246.                 move("forward")
  247.             end
  248.         end
  249.         if i == x then
  250.             if math.fmod(x,2) == 0 then
  251.                 turtle.turnRight()
  252.                 for k=1,(d+1)*(x-1) do
  253.                     move("forward")
  254.                 end
  255.                 turtle.turnRight()
  256.                 dropItems()
  257.                 rednet.send(serverID, "finish", protocol) --когда черепашка закончила
  258.             else
  259.                 turtle.turnRight()
  260.                 move("forward")
  261.                 turtle.turnRight()
  262.                 for l=1,(y+1)*(d+1)+2 do
  263.                     move("forward")
  264.                 end
  265.                 turtle.turnRight()
  266.                 for l=1,(d+1)*(x-1)+1 do
  267.                     move("forward")
  268.                 end
  269.                 turtle.turnRight()
  270.                 dropItems()
  271.                 rednet.send(serverID, "finish", protocol) --когда черепашка закончила
  272.             end
  273.         else
  274.             if math.fmod(i,2) == 1 then
  275.                 turtle.turnRight()
  276.             else
  277.                 turtle.turnLeft()
  278.             end
  279.             for k=1,d+1 do
  280.                 move("forward")
  281.             end
  282.             if math.fmod(i,2) == 1 then
  283.                 turtle.turnRight()
  284.             else
  285.                 turtle.turnLeft()
  286.             end
  287.         end
  288.     end
  289. end
  290.  
  291. --Обработка событий черепашки-дровосека
  292. function workerEvents(event, sender, msg, prot)
  293.     if event == "rednet_message" then
  294.         if msg == "start" then --если сервер прислал старт
  295.             if turtle.getFuelLevel() < 800 and turtle.getItemCount(1) == 0 then
  296.                 rednet.send(serverID, "needbackup", protocol) --если нет топлива, просим помощь
  297.             elseif turtle.getItemCount(2) < x*y then --если нет ростков, просим помощь
  298.                 rednet.send(serverID, "needbackup", protocol)
  299.             else
  300.                 work()
  301.             end
  302.         elseif msg == "catch" then --получаем ресурсы
  303.             if turtle.getItemCount(1) < 10 then --не знаю, как рассчитать
  304.                 rednet.send(helperID, "coal", protocol)
  305.                 return
  306.             end
  307.             if turtle.getItemCount(2) < x*y then --если нет столько ростков, просим у черепашки
  308.                 rednet.send(helperID, "sapling", protocol)
  309.                 return
  310.             end
  311.             rednet.send(helperID, "ok", protocol) --если достаточно, шлем ок
  312.         elseif msg == "disconnect" then --дисконнект сервера
  313.             print("Server has disconnected.")
  314.             error(r)
  315.         end
  316.     end
  317. end
  318.  
  319. --Получает количество угля и ростков
  320. function getCount()
  321.     local a, b = 0, 0
  322.     for i=1,16 do --пробегаемся по инвентарю
  323.         if turtle.getItemCount(i) > 0 then
  324.             local k = turtle.getItemDetail(i)
  325.             if k.name == "minecraft:sapling" then
  326.                 a = a + turtle.getItemCount(i)
  327.             elseif k.name == "minecraft:coal" then
  328.                 b = b + turtle.getItemCount(i)
  329.             end
  330.         end
  331.     end
  332.     return a, b
  333. end
  334.  
  335. --Обработка событий черепашки-помощника
  336. function helperEvents(event, sender, msg, prot)
  337.     if event == "rednet_message" then
  338.         if msg == "refuel" and sender == serverID then --если черепашка просит помощь
  339.             local a, b = getCount()
  340.             if a < 64 or b < 64 then --просто на всякий случай написал 64 и 64
  341.                 rednet.send(serverID, "needbackup", protocol) --если нету, шлем серверу отказ
  342.             else
  343.                 refuel = true
  344.                 rednet.send(workerID, "catch", protocol) --если есть, кидаем черепашке
  345.             end
  346.         elseif msg == "coal" or msg == "sapling" then --в зависимости от ответа, кидаем уголь или cаженец
  347.             if sender == workerID and refuel then
  348.                 for i=1,16 do
  349.                     local k = turtle.getItemDetail(i)
  350.                     if turtle.getItemCount(i) > 0 and k.name == "minecraft:"..msg then
  351.                         turtle.select(i)
  352.                         turtle.drop(1)
  353.                         rednet.send(workerID, "catch", protocol)
  354.                         return
  355.                     end
  356.             end
  357.             end
  358.         elseif msg == "ok" and sender == workerID then --если ок от черепашки, шлем ок серверу
  359.             rednet.send(serverID, "ok", protocol)
  360.             refuel = false
  361.         elseif msg == "disconnect" then --дисконнект сервера
  362.             print("Server has disconnected.")
  363.             error(r)
  364.         end
  365.     end
  366. end
  367.  
  368. --Отправить черепашке-дровосеку событие старт
  369. function sendStart()
  370.     line(1, colors.yellow, "  RTF") --элементы GUI
  371.         line(2, colors.green, "FUEL")
  372.         line(3, colors.green, "SAPLING")
  373.         line(4, colors.blue, "STOP")
  374.         rednet.send(workerID, "start", protocol)
  375. end
  376.  
  377. --Обработка событий компьютера-сервера
  378. function serverEvents(event, arg1, arg2, arg3)
  379.     if event == "monitor_touch" then
  380.             if arg3 == 4 then --нажатие кнопки старт/стоп
  381.             if working then --если работает, то делаем стоп
  382.                 working = false
  383.                 os.cancelTimer(timer)
  384.                 line(1, colors.black, "  RTF")
  385.                 line(4, colors.blue, "START")
  386.             elseif not refuel then --иначе старт
  387.                 working = true
  388.                 sendStart()
  389.             end
  390.         elseif arg3 == 5 then --выходим и шлем дисконнект
  391.             rednet.send(workerID, "disconnect", protocol)
  392.             rednet.send(helperID, "disconnect", protocol)
  393.             term.setBackgroundColor(colors.black)
  394.             term.clear()
  395.             term.setCursorPos(1,1)
  396.             error(r)
  397.                 end
  398.     elseif event == "rednet_message" and arg3 == protocol then
  399.             if arg2 == "needbackup" and arg1 == workerID then --обработка просьб черепашек
  400.             working = false
  401.             rednet.send(helperID, "refuel", protocol)
  402.             line(1, colors.black, "  RTF") --GUI
  403.                 line(2, colors.blue, "FUEL")
  404.                 line(3, colors.blue, "SAPLING")
  405.                 line(4, colors.gray, "START")
  406.             refuel = true
  407.         elseif arg2 == "needbackup" and arg1 == helperID then
  408.             line(4, colors.gray, "START") --GUI
  409.             line(2, colors.red, "REFUEL")
  410.             line(3, colors.red, "SAPLING")
  411.             line(1, colors.black, "  RTF")
  412.             refuel = false
  413.         elseif arg2 == "ok" and arg1 == helperID then --если ок, шлем старт
  414.             refuel = false
  415.             working = true
  416.             sendStart()
  417.         elseif arg2 == "finish" then
  418.             if working then --если черепашка закончила, ставим таймер, если стоит зацикливание
  419.                 timer = os.startTimer(delay)
  420.             else
  421.                 line(1, colors.black, "  RTF")
  422.                 line(4, colors.gray, "START")
  423.             end
  424.         end
  425.     elseif event == "timer" and arg1 == timer then
  426.         sendStart() --при срабатывании таймера
  427.         os.cancelTimer(timer)
  428.     end
  429. end
  430.  
  431. --Основная функция для запуска программы
  432. function start()
  433.     term.setCursorPos(1,1) --подготовка
  434.         term.clear()
  435.     checkArgs()
  436.     print("I am "..getName())
  437.     findModem()
  438.     if thisType == 2 then
  439.         findMonitor()
  440.     end
  441.     print("Searching...")
  442.     findFriends()
  443.     while true do --бесконечный цикл для событий
  444.         local event, sender, msg, prot = os.pullEvent()
  445.         if thisType == 1 then
  446.             workerEvents(event, sender, msg, prot)
  447.         elseif thisType == 2 then
  448.             serverEvents(event, sender, msg, prot)
  449.         elseif thisType == 3 then
  450.             helperEvents(event, sender, msg, prot)
  451.         end
  452.     end
  453. end
  454.  
  455. start() --Start application
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement