Advertisement
Doob

palka-kopalka

Feb 13th, 2017
452
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.63 KB | None | 0 0
  1. 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'}
  2.  
  3. local function i(s) -- функция добавления компонента
  4.   s = component.list(s)() -- получаем компонент из списка
  5.   if s then -- если есть компонент
  6.     return component.proxy(s) -- вернуть прокси
  7.   end
  8. end
  9. local RBT, IC, GLZR, CRFT, GNTR, CLDR, MODEM = i("ob"), i("y_"), i("yz"), i("ft"), i("ne"), i("ch"), i("od")
  10.  
  11. 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()
  12.  
  13. 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
  14.  
  15. CL = function(s) -- активация/деактивация чанклоадера, при наличии
  16.   if CLDR then
  17.     CLDR.setActive(s)
  18.   end
  19. end
  20.  
  21. STURN = function(s) -- вспомогательный поворотник
  22.   while dir~=s do
  23.     TRN((s-dir)%4==1)
  24.   end
  25. end
  26.  
  27. CLRNG = function() -- переход к контейнеру и сброс лута
  28.   Xs, Ys, Zs = x, y, z -- сохранение текущих координат
  29.   HOME() -- переход на точку старта
  30.   STEP(0) -- подъем к сундуку
  31.   GO(Xs, Ys, Zs) -- возвращение к сохраненной точке
  32. end
  33.  
  34. FULLNESS = function() -- проверка заполненности инвентаря
  35.   ad = 1
  36.   for s = 1, iSIZE do
  37.     if CNT(s) > 0 then -- если в слоте что-то есть
  38.       ad = ad + 1 -- обновить счетчик
  39.     end
  40.   end
  41.   return ad/iSIZE
  42. end
  43.  
  44. TRN = function(s) -- функция поворота с обновлением направления
  45.   s = s or false
  46.   if RBT.turn(s) then
  47.     if s then
  48.       dir = (dir+1)%4
  49.     else
  50.       dir = (dir-1)%4
  51.     end
  52.   end
  53. end
  54.  
  55. SLEEP = function(s) -- отправка статусного сообщения и ожидание
  56.   computer.beep(99,5) -- прогудеть 5 секунд
  57.   if MODEM then
  58.     MODEM.broadcast(port, s) -- послать статусное сообщение
  59.     ae = computer.uptime()+30
  60.     while computer.uptime() >= ae do -- ждать 30 секунд
  61.       computer.pullSignal(1)
  62.     end
  63.   end
  64. end
  65.  
  66. DROP = function() -- сброс всех предметов из инвентаря
  67.   for s = 1, iSIZE do
  68.     if CNT(s) > 0 then
  69.       SELECT(s)
  70.       if not RBT.drop(3) then
  71.         while not RBT.drop(3) do
  72.           SLEEP(1)
  73.         end
  74.       end
  75.     end
  76.   end
  77. end
  78.  
  79. STEP = function(s) -- шаг в указанную сторону
  80.   ae, af = DIG(s)
  81.   if not ae and af == 'block' then -- если обнаружен неразрушимый блок
  82.     SLEEP(0) -- сообщить состояние
  83.     HOME() -- вернуться
  84.     CL(false) -- выключить ЧЛ
  85.     return -- прекратить работу
  86.   else
  87.     while DIG(s) do end -- разрушить блок
  88.   end
  89.   if RBT.move(s) then -- если робот переместился - обновить координаты
  90.     if s==0 then y=y-1
  91.     elseif s==1 then y=y+1
  92.     elseif s==3 then
  93.       if dir==0 then z,Z=z+1,Z+1
  94.       elseif dir==1 then x,X=x-1,X-1
  95.       elseif dir==2 then z,Z=z-1,Z-1
  96.       else x,X=x+1,X+1
  97.       end
  98.     end
  99.   end
  100.   if #tWorld.x ~= 0 then -- если робот находится в координатах с помеченным блоком
  101.     for ah = 1, #tWorld.x do
  102.       if x == tWorld.x[ah] and y == tWorld.y[ah] and z == tWorld.z[ah] then
  103.         TR(tWorld.x,ah) -- удалить метку
  104.         TR(tWorld.y,ah)
  105.         TR(tWorld.z,ah)
  106.         break
  107.       end
  108.     end
  109.   end
  110. end
  111.  
  112. GO = function(tX, tY, tZ) -- переход на указанные координаты
  113.   while y ~= tY do
  114.     if y < tY then STEP(1)
  115.     elseif y > tY then STEP(0)
  116.     end
  117.   end
  118.   if x < tX then
  119.     STURN(3)
  120.   elseif x > tX then
  121.     STURN(1)
  122.   end
  123.   while x ~= tX do STEP(3) end
  124.   if z < tZ then
  125.     STURN(0)
  126.   elseif z > tZ then
  127.     STURN(2)
  128.   end
  129.   while z ~= tZ do STEP(3) end
  130. end
  131.  
  132. PACKING = function() -- упаковка ресурсов в блоки
  133.   for s = 1, iSIZE do
  134.     if CNT(s) > 0 then
  135.       for al = 1, #tWaste do
  136.         if STCK(s).name == MC..tWaste[al] then -- если предмет есть в списке отходов
  137.           SELECT(s) -- выбрать слот
  138.           RBT.drop(0) -- выбросить
  139.           break
  140.         end
  141.       end
  142.     end
  143.   end
  144.   if CRFT then -- если есть верстак
  145.     for al = 1, #F do
  146.       for s = 1, 9 do -- проход по слотам рабочей зоны
  147.         if CNT(E[s]) > 0 then -- если в слоте есть предметы
  148.           SELECT(E[s]) -- выбрать слот
  149.           for am = 4, iSIZE-1 do -- перебрать все слоты, кроме рабочих
  150.             if am == 4 or am == 8 or am > 11 then
  151.               TT(am) -- попробовать перенести предмет
  152.             end
  153.           end
  154.         end
  155.       end
  156.       for s = 4, iSIZE do
  157.         if s == 4 or s == 8 or s > 11 then
  158.           if CNT(s) > 8 then -- если количество предметов больше 8
  159.             if STCK(s).name == MC..F[al] then -- если предмет есть в списке крафта
  160.               SELECT(s) -- выбрать слот
  161.               while CNT() > 0 do -- пока не кончатся
  162.                 for am = 1, 9 do
  163.                   TT(E[am],1) -- перенести предмет в рабочую зону
  164.                 end
  165.               end
  166.               SELECT(iSIZE)
  167.               CRFT.craft(64)
  168.             end
  169.           end
  170.         end
  171.       end
  172.     end
  173.   end
  174. end
  175.  
  176. HOME = function() -- возвращение на базу для восстановления заряда и сброса лута
  177.   GO(0, -1, 0)
  178.   STEP(1)
  179.   PACKING()
  180.   ::an::
  181.   ag=nil
  182.   for al = 0, 3 do
  183.     ae = ISIZE(3)
  184.     if ae and ae > 6 then
  185.       ag = K
  186.       DROP()
  187.       if CRFT then -- если есть верстак
  188.         for s = 1, ae do
  189.           af = IC.getStackInSlot(3, s)
  190.           for al = 1, #F do
  191.             if af and af.name == MC..F[al] then -- если предмет в списке крафта
  192.               IC.suckFromSlot(3, s) -- забрать из контейнера
  193.             end
  194.           end
  195.         end
  196.         PACKING()
  197.         DROP()
  198.       end
  199.       break
  200.     end
  201.     TRN()
  202.   end
  203.   if not ag then
  204.     SLEEP(2)
  205.     goto an
  206.   end
  207.   ag = nil
  208.   for ao = 0, 3 do -- зарядка инструмента
  209.     if ISIZE(3) and ISIZE(3) == 1 then -- если размер инвентаря = 1
  210.       while not ag do -- до подтверждения
  211.         if RBT.durability() ~= 1 then -- если инструмент не заряжен
  212.           IC.equip() RBT.drop(3) -- поместить в зарядник
  213.           SLEEP(3) -- подождать
  214.           RBT.suck(3) IC.equip() -- взять из зарядника
  215.         else -- иначе - подтвердить готовность
  216.           ag = K
  217.         end
  218.       end
  219.       break
  220.     end
  221.     TRN()
  222.   end
  223. end
  224.  
  225. RESTR = function()
  226.   if FULLNESS() > 0.9 then -- если инвентарь заполнен
  227.     PACKING() -- произвести упаковку
  228.     if FULLNESS() > 0.9 then -- если мало свободного места
  229.       CLRNG() -- отправится к контейнеру
  230.     end
  231.   end
  232.   if RBT.durability() < 0.1 then -- если заряд инструмента меньше указанного значения
  233.     CLRNG() -- отправится к контейнеру
  234.   end
  235.   if h.energy()/h.maxEnergy() < 0.2 then -- если заряд аккумулятора низок
  236.     if GNTR then -- если есть генератор
  237.       for s = 1, iSIZE do
  238.         if GNTR.insert(64) then -- попробовать заправиться
  239.           GNTR = K -- отметить статус генератора
  240.           SLEEP(4) -- подождать
  241.           break
  242.         end
  243.       end
  244.       if GNTR then -- если генератор заправлен
  245.         GNTR = nil -- сбросить статус генератора
  246.       else -- иначе
  247.         CLRNG() -- вернуться к контейнеру
  248.       end
  249.     else
  250.       CLRNG()
  251.     end
  252.   end
  253. end
  254.  
  255. CL(K)
  256. STEP(0)
  257. while not S do -- определение сторон света
  258.   RBT.turn(K)
  259.   for ap = 0, 3 do
  260.     DIG(3)
  261.     if SCN(D[ap][1],D[ap][2],0,1,1,1)[1] == 0 and RBT.place(3) then
  262.       if SCN(D[ap][1],D[ap][2],0,1,1,1)[1] > 0 then dir = ap break end
  263.     end
  264.   end
  265. end
  266.  
  267. while true do
  268.   for aq = 1, 2 do
  269.     for NDc = 1, O do
  270.       if L==0 then Xn=Xn+1
  271.       elseif L==1 then Zn=Zn+1
  272.       elseif L==2 then Xn=Xn-1
  273.       else Zn=Zn-1
  274.       end
  275.       while not BRDR do
  276.         ac, ad = SCN(-X, -Z, -1, 8, 8, 1), 1 -- сканировать квадрат x8 под роботом
  277.         for as = -Z, 7-Z do
  278.           for at = -X, 7-X do
  279.             if ac[ad] >= min_hardness and ac[ad] <= max_hardness then -- если плотность в пределах указанного диапазона
  280.               TI(tWorld.x, x+at) -- добавить метки по координатам
  281.               TI(tWorld.y, y-1)
  282.               TI(tWorld.z, z+as)
  283.             elseif ac[ad] < -0.3 then -- если плотность близка к бесконечности
  284.               tWorld.x, tWorld.y, tWorld.z, W = {}, {}, {}, y -- очистить метки, отметить границу
  285.               break
  286.             end
  287.             ad = ad+1
  288.           end
  289.         end
  290.         if #tWorld.x ~= 0 then -- пока не добыты все помеченные блоки
  291.           while #tWorld.x ~= 0 do
  292.             D1, D2, IND = HUGE, HUGE, 0 -- задать начальные значения дельт и индекса
  293.             for s = 1, #tWorld.x do -- перебор отмеченых блоков
  294.               D1 = (x-tWorld.x[s])^2+(z-tWorld.z[s])^2 -- рассчитать расстояние до цели
  295.               if D1 < D2 then -- если текущая дельта больше предыдущей
  296.                 D2, IND = D1, s -- сохранить дельту и индекс блока
  297.               end
  298.             end
  299.             GO(tWorld.x[IND], tWorld.y[IND], tWorld.z[IND]) -- перейти на координаты блока
  300.           end
  301.         else
  302.           if not BRDR then -- если граница не указана
  303.             STEP(0) -- опуститься на один блок
  304.           end
  305.         end
  306.         if y == -height then -- если достигнута заданная глубина
  307.           BRDR = y -- отметить границу
  308.         end
  309.       end
  310.       RESTR()
  311.       P = P+1
  312.       if P == nodes then -- если ноды кончились
  313.         HOME()
  314.         SLEEP(5)
  315.         CL(false)
  316.         return
  317.       else
  318.         GO(Xn*8, math.abs(BRDR)+y-1, Zn*8) -- переход к следующей ноде
  319.       end
  320.       X, Z, BRDR = 0, 0, nil
  321.     end
  322.     L = (L+1)%4
  323.   end
  324.   O = O+1
  325. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement