View difference between Paste ID: JT4aAKHF and cZY3P7As
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