SHOW:
|
|
- or go back to the newest paste.
| 1 | - | --Скрипт для робота, для поднятия статов у кропсов или разведения дубликатов (режим задается константой mode) |
| 1 | + | -- robotkiller.lua |
| 2 | - | --Автор: aka_zaratustra осень 2020 |
| 2 | + | -- Робот стоит лицом к рельсам и ломает вагонетки Ваджрой. |
| 3 | - | local ver = "1.1.3" -- версия программы |
| 3 | + | -- Если инвентарь забит больше чем на 50% (кроме слота с Ваджрой), |
| 4 | - | --Историю версий см. в конце файла |
| 4 | + | -- он поворачивается вправо, выкидывает весь лут в сундук и возвращается назад. |
| 5 | ||
| 6 | - | -- схема грядки |
| 6 | + | local robot = require("robot")
|
| 7 | - | --|C1|M1|C2 |
| 7 | + | local event = require("event")
|
| 8 | - | --|M2|C3|M3 |
| 8 | + | |
| 9 | - | --|C4|M4|C5 |
| 9 | + | -- В каком слоте лежит Ваджра |
| 10 | - | --|CH|P0|BR |
| 10 | + | local TOOL_SLOT = 1 |
| 11 | ||
| 12 | - | -- P0 - исходное положение робота. Робот находится на 1 блок выше кропсов (чтобы мог летать над ними), смотрит на север (в сторону грядок). В руках у робота должна быть лопатка Spade. В первом слоте инвентори робота или должны быть палки или он должен быть пустой (робот сам возьмет и положет туда палки) |
| 12 | + | -- Проверять заполненность инвентаря раз в N тиков |
| 13 | - | -- С[n] - дочерние (разводимые) растения |
| 13 | + | -- 1 тик цикла ≈ 0.2 сек, 50 тиков ≈ 10 секунд |
| 14 | - | -- M[n] - материнские растения |
| 14 | + | local CHECK_EVERY_TICKS = 50 |
| 15 | - | -- СН - chest, сундук, куда будут помещаться мешочки с семечками и урожай |
| 15 | + | |
| 16 | - | -- BR - барель с кропсами(палками) |
| 16 | + | -- ===== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ===== |
| 17 | ||
| 18 | - | -- В начале работы материнские кропсы должны быть высажены на грядку. Дочерние (разводимые) могут быть высажены, а может быть голая земля. |
| 18 | + | local function log(msg) |
| 19 | - | -- У робота должны в обязательном порядке присутстовать компоненты: Geolyzer, Inventory Upgrade, Inventory Controller Upgrade |
| 19 | + | print(os.date("[%H:%M:%S] ") .. msg)
|
| 20 | - | -- Рекомендуется для удобства поместить файл с этим скриптом в папку /home/ , а имя файла скрипта добавить в файл /home/.shrc - тогда скрипт будет запускаться при включении робота автоматически |
| 20 | + | |
| 21 | - | -- Если в бочке кончаются кропсы(палки), робот сломает пустые палки, если они есть на поле и завершит свою работу с ошибкой (чтобы всё поле не сожрали сорняки) |
| 21 | + | |
| 22 | - | -- Максимальные статы кропсов, выше которых робот поднимать статы выводимых кропсов не будет, задаются константами max_grow и max_gain |
| 22 | + | -- Проверяем, заполнен ли инвентарь > 50% (кроме слота с Ваджрой) |
| 23 | - | -- Стат resistans робот не поднимает, а при возможости опускает до 0 |
| 23 | + | local function needDump() |
| 24 | - | -- Начиная с версии 1.1.3 робот перестал быть уязвим к коллизиям. Нахождение игрока на пути следования робота больше не приводит к потере роботом маршрута. Робот после столкновения с игроком замирает на секунду, после чего продолжает попытку движения. |
| 24 | + | local invSize = robot.inventorySize() |
| 25 | - | -- Механизм оценки приемлемости (качества) полученного растения менять в функции howInterestingIsThisCrop(с) |
| 25 | + | local lootSlots = invSize - 1 -- слоты 2..invSize |
| 26 | - | -- При наличии интернет карты в роботе, скрипт в робота можно загрузить командой `pastebin get cZY3P7As -f crop_stats.lua` |
| 26 | + | local used = 0 |
| 27 | ||
| 28 | - | -- mode: |
| 28 | + | for slot = 2, invSize do |
| 29 | - | -- 1 - режим поднятия статов кропсов |
| 29 | + | if robot.count(slot) > 0 then |
| 30 | - | -- 2 - режим разведения дубликатов кропсов (НЕ ТЕСТИРОВАЛСЯ! НЕ ИСПОЛЬЗОВАТЬ!) |
| 30 | + | used = used + 1 |
| 31 | - | local mode = 1 |
| 31 | + | end |
| 32 | - | -- выше заданных здесь значений робот понимать статы не будет |
| 32 | + | end |
| 33 | - | local max_grow = 20 -- если больше 23, то кроп начинает вести себя как сорняк |
| 33 | + | |
| 34 | - | local max_gain = 28 |
| 34 | + | log(string.format("Занято %d из %d лут-слотов.", used, lootSlots))
|
| 35 | - | local grow_kill = 24 -- значение стата grow, при котором и выше которого робот будет убивать растение на корню |
| 35 | + | |
| 36 | return used >= math.floor(lootSlots / 2) | |
| 37 | - | local robot = require("robot")
|
| 37 | + | |
| 38 | - | local computer = require("computer")
|
| 38 | + | |
| 39 | - | local component = require("component")
|
| 39 | + | -- Выгружаем весь лут (кроме Ваджры) в сундук СПРАВА от робота |
| 40 | - | local geo = component.geolyzer |
| 40 | + | local function dumpLoot() |
| 41 | - | local cropname |
| 41 | + | log("Инвентарь заполнен >50%. Выгружаю лут в сундук справа.")
|
| 42 | ||
| 43 | - | local c_cropname = {} --имена дочерних кропов
|
| 43 | + | robot.turnRight() -- поворачиваемся к сундуку |
| 44 | - | --статы дочерних кропов |
| 44 | + | |
| 45 | - | local c_gain = {}
|
| 45 | + | local invSize = robot.inventorySize() |
| 46 | - | local c_grow = {}
|
| 46 | + | for slot = 2, invSize do |
| 47 | - | local c_resistans = {}
|
| 47 | + | local count = robot.count(slot) |
| 48 | - | local c_size = {}
|
| 48 | + | if count > 0 then |
| 49 | - | local c_maxSize = {}
|
| 49 | + | robot.select(slot) |
| 50 | local ok, reason = robot.drop() | |
| 51 | - | -- статус может принимать значения: |
| 51 | + | log(string.format( |
| 52 | - | -- "unknown" - неисследованный. назначается при старте, дальше не используется |
| 52 | + | "drop из слота %d, %d шт. -> ok=%s, reason=%s", |
| 53 | - | -- "double crop" - жердочки |
| 53 | + | slot, count, tostring(ok), tostring(reason) |
| 54 | - | -- "growing" - растущий кроп, у которого статы или дошли до целевых или лучше материнских. после вырастания или отправится в сундук или может заменить собой материнский кроп |
| 54 | + | )) |
| 55 | - | local c_status = {"unknown", "unknown", "unknown", "unknown", "unknown"} -- "unknown" для всех пяти дочерних кропов
|
| 55 | + | end |
| 56 | end | |
| 57 | ||
| 58 | - | local m_gain = {}
|
| 58 | + | robot.turnLeft() -- обратно лицом к рельсам |
| 59 | - | local m_grow = {}
|
| 59 | + | robot.select(TOOL_SLOT) -- снова выбираем Ваджру |
| 60 | - | local m_resistans = {}
|
| 60 | + | |
| 61 | ||
| 62 | - | local error_string |
| 62 | + | -- ===== ОСНОВНОЙ ЦИКЛ ===== |
| 63 | - | local bestSeedsSlot --слот в инвентори робота с семенами с лучшими статами |
| 63 | + | |
| 64 | - | local robotLocation -- текущее местонаходение робота. значение из списка: {"С1", "С2", ... , "С5", "M1", "M2", "M3", "M4", "P0"}
|
| 64 | + | log("=== Робот-уборщик вагонеток запущен ===")
|
| 65 | log("Робот должен смотреть на рельсы, сундук с лутом стоит СПРАВА от него.")
| |
| 66 | log("В слоте " .. TOOL_SLOT .. " лежит Ваджра, установлен Upgrade Tool.")
| |
| 67 | - | function robot_error(msg) |
| 67 | + | |
| 68 | - | print("Ошибка: ", msg)
|
| 68 | + | local tick = 0 |
| 69 | - | computer.beep(1000,0.3) |
| 69 | + | |
| 70 | - | computer.beep(1000,0.3) |
| 70 | + | while true do |
| 71 | - | computer.beep(1000,0.3) |
| 71 | + | tick = tick + 1 |
| 72 | - | os.exit() |
| 72 | + | |
| 73 | -- Всегда держим выбранным слот с Ваджрой | |
| 74 | robot.select(TOOL_SLOT) | |
| 75 | - | function robotTryForward() -- роботы пытается сделать шаг вперед, до тех пор, пока ему это не удастся |
| 75 | + | |
| 76 | - | while robot.forward() == nil do |
| 76 | + | -- Бьём всё перед собой (вагонетку) |
| 77 | - | print("Робот столкнулся с препятствием.")
|
| 77 | + | local ok, reason = robot.swing() |
| 78 | - | os.sleep(1) -- останавливаем робота на 1 секунду |
| 78 | + | if ok then |
| 79 | - | end |
| 79 | + | log("Удар по entity перед собой (скорее всего вагонетка). reason=" .. tostring(reason))
|
| 80 | end | |
| 81 | - | -------------------------------------- |
| 81 | + | |
| 82 | - | function get_crop_stat(analyze_result, stat_name) --функция - просматривает таблицу скана блока и возвращает значение поля, имя которого передано в stat_name. если не находит, то возвращает nil |
| 82 | + | -- Раз в CHECK_EVERY_TICKS тиков (~10 сек) проверяем инвентарь |
| 83 | if tick % CHECK_EVERY_TICKS == 0 then | |
| 84 | - | --file = io.open("log.txt", "a") --файл для лога
|
| 84 | + | if needDump() then |
| 85 | dumpLoot() | |
| 86 | - | found = false |
| 86 | + | end |
| 87 | - | for name, v in pairs(analyze_result) do --просмотрим таблицу реультата анализа кропса |
| 87 | + | end |
| 88 | - | |
| 88 | + | |
| 89 | - | pos = string.find(name, stat_name) |
| 89 | + | -- Пауза 0.2 сек + возможность остановить Ctrl+Alt+C |
| 90 | - | --print(pos) |
| 90 | + | local sig = {event.pull(0.2)}
|
| 91 | - | if pos ~= nil then -- если строку в метадате нашли |
| 91 | + | if sig[1] == "interrupted" then |
| 92 | - | found = true |
| 92 | + | log("Получен сигнал interrupted, выхожу.")
|
| 93 | - | --print(v) |
| 93 | + | log("=== Робот-уборщик вагонеток завершён ===")
|
| 94 | - | return v |
| 94 | + | break |
| 95 | - | end |
| 95 | + | end |
| 96 | - | end |
| 96 | + | |
| 97 |