Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local nodes, min_hardness, max_hardness, height, port, tWaste = 9, 2, 5, 64, 99, {'cobblestone','sandstone','stone','dirt','grass','gravel','sand','end_stone','hardened_clay','mossy_cobblestone','planks','fence','torch','nether_brick','nether_brick_fence','nether_brick_stairs','netherrack','soul_sand'}
- local function i(s) -- функция добавления компонента
- s = component.list(s)() -- получаем компонент из списка
- if s then -- если есть компонент
- return component.proxy(s) -- вернуть прокси
- end
- end
- local RBT, IC, GLZR, CRFT, GNTR, CLDR, MODEM = i("ob"), i("y_"), i("yz"), i("ft"), i("ne"), i("ch"), i("od")
- local STCK, ISIZE, SCN, DIG, CNT, TT, SELECT, iSIZE = IC.getStackInInternalSlot, IC.getInventorySize, GLZR.scan, RBT.swing, RBT.count, RBT.transferTo, RBT.select, RBT.inventorySize()
- local tWorld,D,E,F,HUGE,TR,TI,MC,K,L,Xn,Zn,O,P,X,Z,x,y,z,dir,Xs,Ys,Zs,BRDR,GNTR,STEP,TRN,STURN,GO,FULLNESS,PACKING,HOME,CLRNG,CL,RESTR,SLEEP,DROP,D1,D2,IND,ac,ad,ae,af,ag={x={},y={},z={}},{{-1,0},{0,-1},{1,0},[0]={0,1}},{1,2,3,5,6,7,9,10,11},{'redstone','coal','dye','diamond','emerald'},math.huge,table.remove,table.insert,'minecraft:',true,0,0,0,0,0,0,0,0,0,0
- CL = function(s) -- активация/деактивация чанклоадера, при наличии
- if CLDR then
- CLDR.setActive(s)
- end
- end
- STURN = function(s) -- вспомогательный поворотник
- while dir~=s do
- TRN((s-dir)%4==1)
- end
- end
- CLRNG = function() -- переход к контейнеру и сброс лута
- Xs, Ys, Zs = x, y, z -- сохранение текущих координат
- HOME() -- переход на точку старта
- STEP(0) -- подъем к сундуку
- GO(Xs, Ys, Zs) -- возвращение к сохраненной точке
- end
- FULLNESS = function() -- проверка заполненности инвентаря
- ad = 1
- for s = 1, iSIZE do
- if CNT(s) > 0 then -- если в слоте что-то есть
- ad = ad + 1 -- обновить счетчик
- end
- end
- return ad/iSIZE
- end
- TRN = function(s) -- функция поворота с обновлением направления
- s = s or false
- if RBT.turn(s) then
- if s then
- dir = (dir+1)%4
- else
- dir = (dir-1)%4
- end
- end
- end
- SLEEP = function(s) -- отправка статусного сообщения и ожидание
- computer.beep(99,5) -- прогудеть 5 секунд
- if MODEM then
- MODEM.broadcast(port, s) -- послать статусное сообщение
- ae = computer.uptime()+30
- while computer.uptime() >= ae do -- ждать 30 секунд
- computer.pullSignal(1)
- end
- end
- end
- DROP = function() -- сброс всех предметов из инвентаря
- for s = 1, iSIZE do
- if CNT(s) > 0 then
- SELECT(s)
- if not RBT.drop(3) then
- while not RBT.drop(3) do
- SLEEP(1)
- end
- end
- end
- end
- end
- STEP = function(s) -- шаг в указанную сторону
- ae, af = DIG(s)
- if not ae and af == 'block' then -- если обнаружен неразрушимый блок
- SLEEP(0) -- сообщить состояние
- HOME() -- вернуться
- CL(false) -- выключить ЧЛ
- return -- прекратить работу
- else
- while DIG(s) do end -- разрушить блок
- end
- if RBT.move(s) then -- если робот переместился - обновить координаты
- if s==0 then y=y-1
- elseif s==1 then y=y+1
- elseif s==3 then
- if dir==0 then z,Z=z+1,Z+1
- elseif dir==1 then x,X=x-1,X-1
- elseif dir==2 then z,Z=z-1,Z-1
- else x,X=x+1,X+1
- end
- end
- end
- if #tWorld.x ~= 0 then -- если робот находится в координатах с помеченным блоком
- for ah = 1, #tWorld.x do
- if x == tWorld.x[ah] and y == tWorld.y[ah] and z == tWorld.z[ah] then
- TR(tWorld.x,ah) -- удалить метку
- TR(tWorld.y,ah)
- TR(tWorld.z,ah)
- break
- end
- end
- end
- end
- GO = function(tX, tY, tZ) -- переход на указанные координаты
- while y ~= tY do
- if y < tY then STEP(1)
- elseif y > tY then STEP(0)
- end
- end
- if x < tX then
- STURN(3)
- elseif x > tX then
- STURN(1)
- end
- while x ~= tX do STEP(3) end
- if z < tZ then
- STURN(0)
- elseif z > tZ then
- STURN(2)
- end
- while z ~= tZ do STEP(3) end
- end
- PACKING = function() -- упаковка ресурсов в блоки
- for s = 1, iSIZE do
- if CNT(s) > 0 then
- for al = 1, #tWaste do
- if STCK(s).name == MC..tWaste[al] then -- если предмет есть в списке отходов
- SELECT(s) -- выбрать слот
- RBT.drop(0) -- выбросить
- break
- end
- end
- end
- end
- if CRFT then -- если есть верстак
- for al = 1, #F do
- for s = 1, 9 do -- проход по слотам рабочей зоны
- if CNT(E[s]) > 0 then -- если в слоте есть предметы
- SELECT(E[s]) -- выбрать слот
- for am = 4, iSIZE-1 do -- перебрать все слоты, кроме рабочих
- if am == 4 or am == 8 or am > 11 then
- TT(am) -- попробовать перенести предмет
- end
- end
- end
- end
- for s = 4, iSIZE do
- if s == 4 or s == 8 or s > 11 then
- if CNT(s) > 8 then -- если количество предметов больше 8
- if STCK(s).name == MC..F[al] then -- если предмет есть в списке крафта
- SELECT(s) -- выбрать слот
- while CNT() > 0 do -- пока не кончатся
- for am = 1, 9 do
- TT(E[am],1) -- перенести предмет в рабочую зону
- end
- end
- SELECT(iSIZE)
- CRFT.craft(64)
- end
- end
- end
- end
- end
- end
- end
- HOME = function() -- возвращение на базу для восстановления заряда и сброса лута
- GO(0, -1, 0)
- STEP(1)
- PACKING()
- ::an::
- ag=nil
- for al = 0, 3 do
- ae = ISIZE(3)
- if ae and ae > 6 then
- ag = K
- DROP()
- if CRFT then -- если есть верстак
- for s = 1, ae do
- af = IC.getStackInSlot(3, s)
- for al = 1, #F do
- if af and af.name == MC..F[al] then -- если предмет в списке крафта
- IC.suckFromSlot(3, s) -- забрать из контейнера
- end
- end
- end
- PACKING()
- DROP()
- end
- break
- end
- TRN()
- end
- if not ag then
- SLEEP(2)
- goto an
- end
- ag = nil
- for ao = 0, 3 do -- зарядка инструмента
- if ISIZE(3) and ISIZE(3) == 1 then -- если размер инвентаря = 1
- while not ag do -- до подтверждения
- if RBT.durability() ~= 1 then -- если инструмент не заряжен
- IC.equip() RBT.drop(3) -- поместить в зарядник
- SLEEP(3) -- подождать
- RBT.suck(3) IC.equip() -- взять из зарядника
- else -- иначе - подтвердить готовность
- ag = K
- end
- end
- break
- end
- TRN()
- end
- end
- RESTR = function()
- if FULLNESS() > 0.9 then -- если инвентарь заполнен
- PACKING() -- произвести упаковку
- if FULLNESS() > 0.9 then -- если мало свободного места
- CLRNG() -- отправится к контейнеру
- end
- end
- if RBT.durability() < 0.1 then -- если заряд инструмента меньше указанного значения
- CLRNG() -- отправится к контейнеру
- end
- if h.energy()/h.maxEnergy() < 0.2 then -- если заряд аккумулятора низок
- if GNTR then -- если есть генератор
- for s = 1, iSIZE do
- if GNTR.insert(64) then -- попробовать заправиться
- GNTR = K -- отметить статус генератора
- SLEEP(4) -- подождать
- break
- end
- end
- if GNTR then -- если генератор заправлен
- GNTR = nil -- сбросить статус генератора
- else -- иначе
- CLRNG() -- вернуться к контейнеру
- end
- else
- CLRNG()
- end
- end
- end
- CL(K)
- STEP(0)
- while not S do -- определение сторон света
- RBT.turn(K)
- for ap = 0, 3 do
- DIG(3)
- if SCN(D[ap][1],D[ap][2],0,1,1,1)[1] == 0 and RBT.place(3) then
- if SCN(D[ap][1],D[ap][2],0,1,1,1)[1] > 0 then dir = ap break end
- end
- end
- end
- while true do
- for aq = 1, 2 do
- for NDc = 1, O do
- if L==0 then Xn=Xn+1
- elseif L==1 then Zn=Zn+1
- elseif L==2 then Xn=Xn-1
- else Zn=Zn-1
- end
- while not BRDR do
- ac, ad = SCN(-X, -Z, -1, 8, 8, 1), 1 -- сканировать квадрат x8 под роботом
- for as = -Z, 7-Z do
- for at = -X, 7-X do
- if ac[ad] >= min_hardness and ac[ad] <= max_hardness then -- если плотность в пределах указанного диапазона
- TI(tWorld.x, x+at) -- добавить метки по координатам
- TI(tWorld.y, y-1)
- TI(tWorld.z, z+as)
- elseif ac[ad] < -0.3 then -- если плотность близка к бесконечности
- tWorld.x, tWorld.y, tWorld.z, W = {}, {}, {}, y -- очистить метки, отметить границу
- break
- end
- ad = ad+1
- end
- end
- if #tWorld.x ~= 0 then -- пока не добыты все помеченные блоки
- while #tWorld.x ~= 0 do
- D1, D2, IND = HUGE, HUGE, 0 -- задать начальные значения дельт и индекса
- for s = 1, #tWorld.x do -- перебор отмеченых блоков
- D1 = (x-tWorld.x[s])^2+(z-tWorld.z[s])^2 -- рассчитать расстояние до цели
- if D1 < D2 then -- если текущая дельта больше предыдущей
- D2, IND = D1, s -- сохранить дельту и индекс блока
- end
- end
- GO(tWorld.x[IND], tWorld.y[IND], tWorld.z[IND]) -- перейти на координаты блока
- end
- else
- if not BRDR then -- если граница не указана
- STEP(0) -- опуститься на один блок
- end
- end
- if y == -height then -- если достигнута заданная глубина
- BRDR = y -- отметить границу
- end
- end
- RESTR()
- P = P+1
- if P == nodes then -- если ноды кончились
- HOME()
- SLEEP(5)
- CL(false)
- return
- else
- GO(Xn*8, math.abs(BRDR)+y-1, Zn*8) -- переход к следующей ноде
- end
- X, Z, BRDR = 0, 0, nil
- end
- L = (L+1)%4
- end
- O = O+1
- end
Add Comment
Please, Sign In to add comment