Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Установка переменных
- args = { ... } --аргументы
- thisType = 0 --тип компьютера
- workerID = 0 --айди черепашки-дровосека
- helperID = 0 --айди черепашки-помощника
- serverID = 0 --айди сервера
- x, y, d = 0, 0, 0 --размеры поля с деревьями
- sapling = false --дополнительная переменная, если на пути саженец
- protocol = "TurtleFProto" --название протокола
- timer = 0 --переменная таймера для зацикливания работы
- refuel = false --переменная с состоянием зарядки
- delay = 600 --задержка между работой черепашки
- working = false --переменная с состоянием зацикливания
- --Рисует линию текста (GUI)
- function line(y, backcolor, text)
- term.setCursorPos(1, y)
- term.setBackgroundColor(backcolor)
- term.clearLine()
- term.write(text)
- end
- --Поиск модема
- function findModem()
- sides = {"front","back","left","right","top","bottom"}
- for i=1,6 do
- if peripheral.getType(sides[i]) == "modem" then
- rednet.open(sides[i])
- return
- end
- end
- print("Need wireless modem!") --сообщение о том, что модем не найден
- error(r)
- end
- --Получает должность компьютера
- function getName()
- if thisType == 1 then
- workerID = os.getComputerID()
- return "worker"
- elseif thisType == 2 then
- serverID = os.getComputerID()
- return "server"
- elseif thisType == 3 then
- helperID = os.getComputerID()
- return "helper"
- end
- end
- --Поиск других компьютеров
- function findFriends()
- rednet.broadcast("zdarova_ya_"..getName(), protocol) --приветствие
- while true do
- local event, sender, msg, prot = os.pullEvent("rednet_message")
- if prot == protocol then
- if string.find(msg, "zdarova") then --ответ
- rednet.send(sender, "privet_ya_"..getName(), protocol)
- end
- if string.find(msg, "ya_server") and thisType ~= 2 then --тут идет разбор ответившего клиента
- serverID = sender
- print("Server ID: "..serverID)
- elseif string.find(msg, "ya_worker") and thisType ~= 1 then
- workerID = sender
- print("Worker ID: "..workerID)
- elseif string.find(msg, "ya_helper") and thisType ~= 3 then
- helperID = sender
- print("Helper ID: "..helperID)
- end
- if serverID ~= 0 and workerID ~= 0 and helperID ~= 0 then --настройка монитора (GUI)
- if thisType == 2 then
- print("Look at the monitor! Program has been started.")
- term.redirect(monitor)
- monitor.setTextScale(1)
- line(1, colors.black, " RTF")
- line(2, colors.green, "FUEL")
- line(3, colors.green, "SAPLING")
- line(4, colors.gray, "START")
- line(5, colors.gray, "EXIT")
- end
- return
- end
- end
- end
- end
- --Анализ аргументов
- function checkArgs()
- if args[1] == nil then
- print("Need args!") --если вообще нет
- error(r)
- else
- thisType = tonumber(args[1]) --аргумент типа
- end
- if args[4] == nil and thisType == 1 then --проверка наличия размеров поля
- print("Need args!")
- error(r)
- elseif thisType == 1 then --если есть, присваивание
- x, y, d = tonumber(args[2]), tonumber(args[3]), tonumber(args[4])
- if args[5] ~= nil then --проверка протокола
- protocol = args[5]
- end
- elseif thisType == 2 and args[2] ~= nil then --если сервер, то проверяется задержка и протокол
- delay = tonumber(args[2])
- if args[3] ~= nil then
- protocol = args[3]
- end
- elseif thisType == 3 and args[2] ~= nil then --если помощник, то только протокол
- protocol = args[2]
- end
- end
- --Перемещение черепашки
- function move(w)
- turtle.suck() --забирание дропа
- if turtle.getFuelLevel() == 0 then --заправка
- turtle.refuel(1)
- end
- if w == "forward" then --тут скриптик, чтобы мобы или случайные блоки на пути не сбивали
- while true do
- local res = turtle.forward()
- if res then
- break
- else
- turtle.dig()
- turtle.select(16)
- turtle.equipLeft()
- turtle.attack()
- turtle.equipLeft()
- turtle.select(1)
- findModem()
- sleep(1)
- end
- end
- elseif w == "up" then --вверх
- turtle.up()
- elseif w == "down" then --вниз
- turtle.down()
- end
- end
- --Поиск монитора
- function findMonitor()
- local e = peripheral.getNames() --перебор периферии
- for i=1,#e do
- if peripheral.getType(e[i]) == "monitor" then
- local m = peripheral.wrap(e[i])
- if m.isColor() then
- monitor = m
- return
- end
- end
- end
- if monitor == nil then
- print("Need advanced monitor!") --сообщение об ошибке
- error(r)
- end
- end
- --Выгрузка вещей после работы
- function dropItems()
- checkSapling()
- for i=1,15 do
- if turtle.getItemCount(i) > 0 then
- local d = turtle.getItemDetail(i) --в сундук выгружаются только яблоко и бревна
- turtle.select(i)
- if d.name == "minecraft:log" or d.name == "minecraft:apple" then
- turtle.dropDown()
- elseif d.name ~= "minecraft:coal" and d.name ~= "minecraft:sapling" then
- turtle.dropUp()
- end
- end
- end
- turtle.select(1)
- end
- --Функция для складывания ростков в один слот
- function checkSapling()
- for i=1,15 do
- if turtle.getItemCount(i) > 0 then
- local d = turtle.getItemDetail(i)
- if d.name == "minecraft:sapling" then
- turtle.select(i)
- if turtle.getItemCount(2) < 64 then
- turtle.transferTo(2, turtle.getItemSpace(2))
- end
- if turtle.getItemCount(i) > 0 then
- return
- end
- end
- end
- end
- end
- --Функция движения для черепашки-дровосека
- --Здесь идет поход по полю, срубание деревьев и рассадка саженцев
- function work()
- for i=1,x do
- for j=1,y do
- if sapling then
- for k=1,d-1 do
- move("forward")
- end
- sapling = false
- else
- for k=1,d+1 do
- move("forward")
- end
- end
- local a, b = turtle.inspect()
- while b.name == "minecraft:log" do
- turtle.dig()
- if turtle.inspectUp() then
- turtle.digUp()
- end
- move("up")
- a, b = turtle.inspect()
- end
- while not turtle.inspectDown() do
- move("down")
- end
- if not turtle.inspect() then
- turtle.select(2)
- turtle.place()
- turtle.select(1)
- end
- local a, b = turtle.inspect()
- if b.name == "minecraft:sapling" then
- turtle.turnLeft()
- move("forward")
- turtle.turnRight()
- move("forward")
- move("forward")
- turtle.turnRight()
- move("forward")
- turtle.turnLeft()
- sapling = true
- end
- end
- if sapling then
- for k=1,d+1 do
- move("forward")
- end
- sapling = false
- else
- for k=1,d+3 do
- move("forward")
- end
- end
- if i == x then
- if math.fmod(x,2) == 0 then
- turtle.turnRight()
- for k=1,(d+1)*(x-1) do
- move("forward")
- end
- turtle.turnRight()
- dropItems()
- rednet.send(serverID, "finish", protocol) --когда черепашка закончила
- else
- turtle.turnRight()
- move("forward")
- turtle.turnRight()
- for l=1,(y+1)*(d+1)+2 do
- move("forward")
- end
- turtle.turnRight()
- for l=1,(d+1)*(x-1)+1 do
- move("forward")
- end
- turtle.turnRight()
- dropItems()
- rednet.send(serverID, "finish", protocol) --когда черепашка закончила
- end
- else
- if math.fmod(i,2) == 1 then
- turtle.turnRight()
- else
- turtle.turnLeft()
- end
- for k=1,d+1 do
- move("forward")
- end
- if math.fmod(i,2) == 1 then
- turtle.turnRight()
- else
- turtle.turnLeft()
- end
- end
- end
- end
- --Обработка событий черепашки-дровосека
- function workerEvents(event, sender, msg, prot)
- if event == "rednet_message" then
- if msg == "start" then --если сервер прислал старт
- if turtle.getFuelLevel() < 800 and turtle.getItemCount(1) == 0 then
- rednet.send(serverID, "needbackup", protocol) --если нет топлива, просим помощь
- elseif turtle.getItemCount(2) < x*y then --если нет ростков, просим помощь
- rednet.send(serverID, "needbackup", protocol)
- else
- work()
- end
- elseif msg == "catch" then --получаем ресурсы
- if turtle.getItemCount(1) < 10 then --не знаю, как рассчитать
- rednet.send(helperID, "coal", protocol)
- return
- end
- if turtle.getItemCount(2) < x*y then --если нет столько ростков, просим у черепашки
- rednet.send(helperID, "sapling", protocol)
- return
- end
- rednet.send(helperID, "ok", protocol) --если достаточно, шлем ок
- elseif msg == "disconnect" then --дисконнект сервера
- print("Server has disconnected.")
- error(r)
- end
- end
- end
- --Получает количество угля и ростков
- function getCount()
- local a, b = 0, 0
- for i=1,16 do --пробегаемся по инвентарю
- if turtle.getItemCount(i) > 0 then
- local k = turtle.getItemDetail(i)
- if k.name == "minecraft:sapling" then
- a = a + turtle.getItemCount(i)
- elseif k.name == "minecraft:coal" then
- b = b + turtle.getItemCount(i)
- end
- end
- end
- return a, b
- end
- --Обработка событий черепашки-помощника
- function helperEvents(event, sender, msg, prot)
- if event == "rednet_message" then
- if msg == "refuel" and sender == serverID then --если черепашка просит помощь
- local a, b = getCount()
- if a < 64 or b < 64 then --просто на всякий случай написал 64 и 64
- rednet.send(serverID, "needbackup", protocol) --если нету, шлем серверу отказ
- else
- refuel = true
- rednet.send(workerID, "catch", protocol) --если есть, кидаем черепашке
- end
- elseif msg == "coal" or msg == "sapling" then --в зависимости от ответа, кидаем уголь или cаженец
- if sender == workerID and refuel then
- for i=1,16 do
- local k = turtle.getItemDetail(i)
- if turtle.getItemCount(i) > 0 and k.name == "minecraft:"..msg then
- turtle.select(i)
- turtle.drop(1)
- rednet.send(workerID, "catch", protocol)
- return
- end
- end
- end
- elseif msg == "ok" and sender == workerID then --если ок от черепашки, шлем ок серверу
- rednet.send(serverID, "ok", protocol)
- refuel = false
- elseif msg == "disconnect" then --дисконнект сервера
- print("Server has disconnected.")
- error(r)
- end
- end
- end
- --Отправить черепашке-дровосеку событие старт
- function sendStart()
- line(1, colors.yellow, " RTF") --элементы GUI
- line(2, colors.green, "FUEL")
- line(3, colors.green, "SAPLING")
- line(4, colors.blue, "STOP")
- rednet.send(workerID, "start", protocol)
- end
- --Обработка событий компьютера-сервера
- function serverEvents(event, arg1, arg2, arg3)
- if event == "monitor_touch" then
- if arg3 == 4 then --нажатие кнопки старт/стоп
- if working then --если работает, то делаем стоп
- working = false
- os.cancelTimer(timer)
- line(1, colors.black, " RTF")
- line(4, colors.blue, "START")
- elseif not refuel then --иначе старт
- working = true
- sendStart()
- end
- elseif arg3 == 5 then --выходим и шлем дисконнект
- rednet.send(workerID, "disconnect", protocol)
- rednet.send(helperID, "disconnect", protocol)
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1,1)
- error(r)
- end
- elseif event == "rednet_message" and arg3 == protocol then
- if arg2 == "needbackup" and arg1 == workerID then --обработка просьб черепашек
- working = false
- rednet.send(helperID, "refuel", protocol)
- line(1, colors.black, " RTF") --GUI
- line(2, colors.blue, "FUEL")
- line(3, colors.blue, "SAPLING")
- line(4, colors.gray, "START")
- refuel = true
- elseif arg2 == "needbackup" and arg1 == helperID then
- line(4, colors.gray, "START") --GUI
- line(2, colors.red, "REFUEL")
- line(3, colors.red, "SAPLING")
- line(1, colors.black, " RTF")
- refuel = false
- elseif arg2 == "ok" and arg1 == helperID then --если ок, шлем старт
- refuel = false
- working = true
- sendStart()
- elseif arg2 == "finish" then
- if working then --если черепашка закончила, ставим таймер, если стоит зацикливание
- timer = os.startTimer(delay)
- else
- line(1, colors.black, " RTF")
- line(4, colors.gray, "START")
- end
- end
- elseif event == "timer" and arg1 == timer then
- sendStart() --при срабатывании таймера
- os.cancelTimer(timer)
- end
- end
- --Основная функция для запуска программы
- function start()
- term.setCursorPos(1,1) --подготовка
- term.clear()
- checkArgs()
- print("I am "..getName())
- findModem()
- if thisType == 2 then
- findMonitor()
- end
- print("Searching...")
- findFriends()
- while true do --бесконечный цикл для событий
- local event, sender, msg, prot = os.pullEvent()
- if thisType == 1 then
- workerEvents(event, sender, msg, prot)
- elseif thisType == 2 then
- serverEvents(event, sender, msg, prot)
- elseif thisType == 3 then
- helperEvents(event, sender, msg, prot)
- end
- end
- end
- start() --Start application
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement