Advertisement
lambdaCraft

mc-api

Jan 18th, 2020
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 25.07 KB | None | 0 0
  1. --lua
  2. ------------    Created by : luochen1990 (Luo)   ------------------------
  3.  
  4. const = {
  5.     slotnum = 16 ;
  6.     needfuel = true ;
  7.     debuging = false ;
  8.     virtual = (turtle == nil) ;
  9. } ;
  10.  
  11. useage = {
  12.     link = "link(p1, ..., [f])\n such as: link(go(1,0,2), scan('d',2), dig.down)\n" ;
  13.     go = "go(x, y, z, [p])\n such as: go(1,0,2)\n or: go(pos , [p])\n such as: go({x=1,z=2})\n" ;
  14.     scan = "scan(dir, times, [p])\n such as: scan('f',2)\n" ;
  15.     cycle = "cycle(dir, round, [times] , [p])\n such as: cycle('r', 'X##XX##X')\n" ;
  16.     digLine = "digLine(dir, maxdis, [p])\n" ;
  17.     digAll = "digAll(slots, [maxdis], [p])\n" ;
  18.     digExcept = "digExcept(slots, [maxdis], [p])\n" ;
  19. } ;
  20.  
  21. ------------------------------debuging code---------------------------------------
  22.  
  23. baseAPIs = {
  24.     "turnLeft" , "turnRight" , "select" ,
  25.     "getItemCount" , "getItemSpace" , "getFuelLevel" ,
  26.     "refuel" , "compareTo" ,
  27.     "up" , "digUp" , "placeUp" , "detectUp" , "compareUp" , "attackUp" , "suckUp" , "dropUp" ,
  28.     "down" , "digDown" , "placeDown" , "detectDown" , "compareDown" , "attackDown" , "suckDown" , "dropDown" ,
  29.     "forward" , "dig" , "place" , "detect" , "compare" , "attack" , "suck" , "drop" ,
  30. } ;
  31.  
  32. if const.virtual then turtle = {} end ;
  33. for i , k in ipairs(baseAPIs) do
  34.     local turtleWithoutEcho = turtle[k] ;
  35.     local run = function(...)
  36.         if turtleWithoutEcho then return turtleWithoutEcho(...) end ;
  37.         if i >= 1 and i <= 3 then return nil end ;
  38.         if i >= 4 and i <= 6 then return 10000 end ;
  39.         if i >= 7 and i <= 8 then return true end ;
  40.         if i >= 9 then return true end ;
  41.     end ;
  42.     turtle[k] = function(...)
  43.         local r = run(...) ;
  44.         if const.debuging or const.virtual then
  45.             print(status.toString()..' -- '..k..'('..table.concat({...} , ',')..'): ' , r) ;
  46.         end ;
  47.         return r ;
  48.     end ;
  49. end ;
  50.  
  51. ------------------------------base utils---------------------------------------
  52.  
  53. withDefault = function (x , y)
  54.     if x == nil then return y else return x end ;
  55. end ;
  56.  
  57. withParam = function (f , p)
  58.     return function ()
  59.         return f(unpack(p)) ;
  60.     end ;
  61. end ;
  62.  
  63. math.randomseed(os.time())
  64. try = function (f , t)
  65.     if f() == true then return true end ;
  66.     local interval = 0.5 ;
  67.     local time = 0 ;
  68.     while time < t do
  69.         local x = (math.random() + 0.5) * interval ;
  70.         sleep (x) ;
  71.         if f() == true then return true end ;
  72.         time = time + x ;
  73.         interval = interval * 2 ;
  74.     end ;
  75.     return false ;
  76. end ;
  77.  
  78. deepcopy = function (object)
  79.     local lookup_table = {} ;
  80.     local function _copy(object)
  81.         if type(object) ~= "table" then
  82.             return object ;
  83.         elseif lookup_table[object] then
  84.             return lookup_table[object] ;
  85.         end ;
  86.         local new_table = {} ;
  87.         lookup_table[object] = new_table ;
  88.         for index, value in pairs(object) do
  89.             new_table[_copy(index)] = _copy(value) ;
  90.         end ;
  91.         return setmetatable(new_table, getmetatable(object)) ;
  92.     end ;
  93.     return _copy(object) ;
  94. end ;
  95.  
  96. memorized = function(f)
  97.     local mem = {} ;
  98.     setmetatable(mem , {__mode = "kv"}) ;
  99.     return function (...)
  100.         local r = mem[{...}] ;
  101.         if r == nil then
  102.             r = f(...) ;
  103.             mem[{...}] = r ;
  104.         end ;
  105.         return r ;
  106.     end ;
  107. end ;
  108.  
  109. --------------------------------turtle status--------------------------------------
  110.  
  111. workMode = {
  112.     destroy = false ;
  113.     force = false ;
  114.     tryTime = 10 ;
  115.     echo = false ;
  116.     autoRefuel = const.needfuel ;
  117.    
  118.     asDefault = function(p , default , changed)
  119.         if type(default) ~= 'table' then
  120.             changed , default = default , changed ;
  121.         end ;
  122.         if p == nil and default == nil and (not changed) then
  123.             return workMode ;
  124.         else
  125.             local r = {} ;
  126.             if p then
  127.                 r = deepcopy(p) ;
  128.             end ;
  129.             for k , v in pairs(workMode) do
  130.                 local dk = nil ;
  131.                 if default then
  132.                     dk = default[k] ;
  133.                 end ;
  134.                 r[k] = withDefault(withDefault(r[k] , dk) , v) ;
  135.             end ;
  136.             r.asDefault = nil ;
  137.             return r ;
  138.         end ;
  139.     end ;
  140. } ;
  141.  
  142. status = {
  143.     pos = {x = 0 , y = 0 , z = 0} ;
  144.     dir = 'f' ;
  145.     lastPos = {x = 0 , y = 0 , z = 0} ;
  146.     slots = {fuel = 1} ;
  147.    
  148.     posAdd = function (a , b)
  149.         local r = {}
  150.         r.x = (a.x or 0) + (b.x or 0) ;
  151.         r.y = (a.y or 0) + (b.y or 0) ;
  152.         r.z = (a.z or 0) + (b.z or 0) ;
  153.         return r ;
  154.     end ;
  155.     posDif = function (a , b)
  156.         local r = {}
  157.         r.x = (a.x or 0) - (b.x or 0) ;
  158.         r.y = (a.y or 0) - (b.y or 0) ;
  159.         r.z = (a.z or 0) - (b.z or 0) ;
  160.         return r ;
  161.     end ;
  162.     posDis = function (a , b)
  163.         local dif = status.posDif (a , b or {}) ;
  164.         return math.abs(dif.x or 0) + math.abs(dif.y or 0) + math.abs(dif.z or 0) ;
  165.     end ;
  166.     dirDif = function (a , b)
  167.         return (status.numberedDirection[a] - status.numberedDirection[b] + 4) % 4 ;
  168.     end ;
  169.    
  170.     numberedDirection = {
  171.         f = 0 ; l = 1 ; b = 2 ; r = 3 ; u = 4 ; d = 5 ;
  172.     } ;
  173.     negativeDirection = {
  174.         f = 'b' ; b = 'f' ; l = 'r' ; r = 'l' ; u = 'd' ; d = 'u' ;
  175.     } ;
  176.     outerDirection = {
  177.         f = 'forward' ; l = 'left' ; b = 'back' ; r = 'right' ; u = 'up' ; d = 'down' ;
  178.     } ;
  179.     innerDirection = {
  180.         [0] = 'f' ; [1] = 'l' ; [2] = 'b' ; [3] = 'r' ; [4] = 'u' ; [5] = 'd' ;
  181.         f = 'f' ; l = 'l' ; b = 'b' ; r = 'r' ; u = 'u' ; d = 'd' ;
  182.         F = 'f' ; L = 'l' ; B = 'b' ; R = 'r' ; U = 'u' ; D = 'd' ;
  183.         forward = 'f' ; left = 'l' ; back = 'b' ; right = 'r' ; up = 'u' ; down = 'd' ;
  184.         [{x = 1}] = 'f' , [{x = -1}] = 'b' , [{y = 1}] = 'l' ,
  185.         [{y = -1}] = 'r' , [{z = 1}] = 'u' , [{z = -1}] = 'd' ,
  186.     } ;
  187.     dif = {
  188.         f = {x = 1} ; b = {x = -1} ; l = {y = 1} ;
  189.         r = {y = -1} ; u = {z = 1} ; d = {z = -1} ;
  190.     } ;
  191.     coord = {
  192.         f = 'x' ; b = 'x' ; l = 'y' ; r = 'y' ; u = 'z' ; d = 'z' ;
  193.     } ;
  194.    
  195.     turnTo = function(dir)
  196.         if status.numberedDirection[dir] > 3 then return end ;
  197.         local dirDif = (status.numberedDirection[dir] - status.numberedDirection[status.dir] + 4) % 4 ;
  198.         if dirDif == 1 then
  199.             turtle.turnLeft() ;
  200.         elseif dirDif == 2 then
  201.             turtle.turnLeft() ;
  202.             turtle.turnLeft() ;
  203.         elseif dirDif == 3 then
  204.             turtle.turnRight() ;
  205.         end ;
  206.         status.dir = dir ;
  207.     end ;
  208.    
  209.     reset = function(s)
  210.         local rotate = function(v)
  211.             return {x = -v.y , y = v.x , z = v.z} ;
  212.         end ;
  213.         s = withDefault(s , {pos = status.pos , dir = status.dir}) ;
  214.         s.pos = withDefault(s.pos , {x = 0 , y = 0 , z = 0}) ;
  215.         s.dir = withDefault(s.dir , 'f') ;
  216.         local old = {} ;
  217.         local rot = status.dirDif('f' , s.dir) ;
  218.         old.pos = status.posDif({x = 0 , y = 0 , z = 0} , s.pos) ;
  219.         old.dir = status.innerDirection[rot] ;
  220.         status.pos = status.posDif(status.pos , s.pos) ;
  221.         status.dir = status.innerDirection[status.dirDif(status.dir , s.dir)] ;
  222.         for i = 1 , rot do
  223.             old.pos = rotate(old.pos) ;
  224.             status.pos = rotate(status.pos) ;
  225.         end ;
  226.         return old ;
  227.     end ;
  228.    
  229.     toString = function(st)
  230.         local s = withDefault(st , status) ;
  231.         s.pos.x = withDefault(s.pos.x , 0) ;
  232.         s.pos.y = withDefault(s.pos.y , 0) ;
  233.         s.pos.z = withDefault(s.pos.z , 0) ;
  234.         return string.format('<%-2d %-2d %-2d %s>' , s.pos.x , s.pos.y , s.pos.z , s.dir) ;
  235.     end ;
  236. } ;
  237.  
  238. ----------------------------- base api Factory -----------------------------
  239.  
  240. local apiFactory = function(op , dir)
  241.     local directionBindedApis = function(dir)
  242.         if dir == 'u' then
  243.             return turtle.up , turtle.digUp , turtle.placeUp , turtle.detectUp , turtle.compareUp , turtle.attackUp , turtle.suckUp , turtle.dropUp ;
  244.         elseif dir == 'd' then
  245.             return turtle.down , turtle.digDown , turtle.placeDown , turtle.detectDown , turtle.compareDown , turtle.attackDown , turtle.suckDown , turtle.dropDown ;
  246.         else
  247.             return turtle.forward , turtle.dig , turtle.place , turtle.detect , turtle.compare , turtle.attack , turtle.suck , turtle.drop ;
  248.         end ;
  249.     end ;
  250.     local mov , dig , pla , det , cmp , atk , suk , dro = directionBindedApis (dir) ;
  251.    
  252.     if op == 'move' then
  253.         return function(p)
  254.             p = workMode.asDefault(p) ;
  255.            
  256.             if p.echo then
  257.                 io.write('M') ;
  258.                 io.write(dir) ;
  259.                 if p.destroy then io.write('*') else io.write(' ') end ;
  260.             end
  261.            
  262.             if p.autoRefuel then
  263.                 refuel(status.pos.x + status.pos.y + status.pos.z) ;
  264.             end ;
  265.            
  266.             local r = false ;
  267.             if status.negativeDirection[dir] == status.dir then
  268.                 r = turtle.back() ;
  269.             end ;
  270.             if not r then
  271.                 status.turnTo(dir) ;
  272.                 movx = function ()
  273.                     if mov() then return true end ;
  274.                     if p.destroy then
  275.                         while dig() do end ;
  276.                         if mov() then return true end ;
  277.                     end ;
  278.                     if p.force then
  279.                         while atk() do end ;
  280.                         if mov() then return true end ;
  281.                     end ;
  282.                     return false ;
  283.                 end ;
  284.                 r = try(movx , p.tryTime) ;
  285.             end
  286.             if r then
  287.                 status.lastPos = status.pos ;
  288.                 status.pos = status.posAdd (status.pos , status.dif[dir]) ;
  289.                 if p.echo then print (' -> ' , status.toString()) end ;
  290.             else
  291.                 if p.echo then print ('FALSE') end ;
  292.             end ;
  293.             return r ;
  294.         end ;
  295.  
  296.     elseif op == 'place' then
  297.         return function(s , p)
  298.             if type(s) == 'table' then
  299.                 s , p = p , s ;
  300.             end ;
  301.            
  302.             p = workMode.asDefault(p) ;
  303.  
  304.             if s ~= nil then
  305.                 if s >= 1 and s <= const.slotnum then
  306.                     local count = turtle.getItemCount(s) ;
  307.                     if count > 1 then
  308.                         turtle.select(s) ;
  309.                     else
  310.                         if count == 1 and turtle.getItemSpace(s) == 0 then
  311.                             local lastone = slot.last(s) ;
  312.                             if lastone > s then
  313.                                 turtle.select(lastone) ;
  314.                             else
  315.                                 slot.waitingForReloading(s , p.tryTime * 3) ;
  316.                             end ;
  317.                         else
  318.                             slot.packUp(s) ;
  319.                             turtle.select(s) ;
  320.                             if not (turtle.getItemCount(s) > 1) then
  321.                                 if p.tryTime >= 10 then
  322.                                     print("More materials needed !") ;
  323.                                     slot.waitingForReloading(s , p.tryTime * 3) ;
  324.                                 else
  325.                                     return false ;
  326.                                 end ;
  327.                             end ;
  328.                         end ;
  329.                     end ;
  330.                 elseif s == 0 then
  331.                     if p.destroy then
  332.                         while dig() do end ;
  333.                         return true ;
  334.                     else
  335.                         return not det() ;
  336.                     end ;
  337.                 else
  338.                     return false ;
  339.                 end ;
  340.             end ;
  341.            
  342.             if p.echo then
  343.                 io.write('P') ;
  344.                 io.write(dir) ;
  345.                 if p.destroy then io.write('*') else io.write(' ') end ;
  346.             end
  347.            
  348.             local r = false ;
  349.             status.turnTo(dir) ;
  350.             plax = function ()
  351.                 if pla() or cmp() then return true end ;
  352.                 if p.destroy then
  353.                     while dig() do end ;
  354.                     if pla() or cmp() then return true end ;
  355.                 end ;
  356.                 if p.force then
  357.                     while atk() do end ;
  358.                     if pla() or cmp() then return true end ;
  359.                 end ;
  360.                 return false ;
  361.             end ;
  362.             r = try(plax , p.tryTime) ;
  363.            
  364.             if r then
  365.                 if p.echo then print (' -- ' , status.toString()) end ;
  366.             else
  367.                 if p.echo then print ('FALSE') end ;
  368.             end ;
  369.             return r ;
  370.         end ;
  371.  
  372.     elseif op == 'detect' then
  373.         return function(p)
  374.             p = workMode.asDefault(p) ;
  375.            
  376.             if p.echo then
  377.                 io.write(string.format('DET\t%s\t' , dir)) ;
  378.             end ;
  379.            
  380.             status.turnTo(dir) ;
  381.             local r = det() ;
  382.             if r then
  383.                 if p.echo then print ('TRUE') end ;
  384.                 if p.echo then print (status.toString()) end ;
  385.             else
  386.                 if p.echo then print ('FALSE') end ;
  387.             end ;
  388.             return r ;
  389.         end ;
  390.  
  391.     elseif op == 'dig' then
  392.         return function(p)
  393.             p = workMode.asDefault(p) ;
  394.            
  395.             if p.echo then
  396.                 io.write(string.format('DIG\t%s\t' , dir)) ;
  397.             end ;
  398.  
  399.             status.turnTo(dir) ;
  400.             local r = dig() ;
  401.            
  402.             if r then
  403.                 if p.echo then print ('TRUE') end ;
  404.                 if p.echo then print (status.toString()) end ;
  405.             else
  406.                 if p.echo then print ('FALSE') end ;
  407.             end ;
  408.             return r ;
  409.         end ;
  410.  
  411.     elseif op == 'compare' then
  412.         return function(s , p)
  413.             if type(s) == 'table' then
  414.                 s , p = p , s ;
  415.             end ;
  416.             p = workMode.asDefault(p) ;
  417.            
  418.             if s ~= nil then
  419.                 turtle.select(s) ;
  420.             end ;
  421.  
  422.             if p.echo then
  423.                 io.write(string.format('CMP\t%s\t' , dir)) ;
  424.             end ;
  425.            
  426.             status.turnTo(dir) ;
  427.             local r = cmp() ;
  428.             if r then
  429.                 if p.echo then print ('TRUE') end ;
  430.                 if p.echo then print (status.toString()) end ;
  431.             else
  432.                 if p.echo then print ('FALSE') end ;
  433.             end ;
  434.             return r ;
  435.         end ;
  436.    
  437.     elseif op == 'attack' then
  438.         return function(p)
  439.             p = workMode.asDefault(p) ;
  440.            
  441.             if p.echo then
  442.                 if p.destroy then
  443.                     io.write(string.format('ATK\t%s*\t' , dir)) ;
  444.                 else
  445.                     io.write(string.format('ATK\t%s\t' , dir)) ;
  446.                 end ;
  447.             end ;
  448.  
  449.             status.turnTo(dir) ;
  450.             local r = atk() ;
  451.            
  452.             if r then
  453.                 if p.echo then print ('TRUE') end ;
  454.                 if p.echo then print (status.toString()) end ;
  455.             else
  456.                 if p.echo then print ('FALSE') end ;
  457.             end ;
  458.             return r ;
  459.         end ;
  460.    
  461.     elseif op == 'suck' then
  462.         return function(p)
  463.             p = workMode.asDefault(p) ;
  464.            
  465.             if p.echo then
  466.                 io.write(string.format('SUCK\t%s\t' , dir)) ;
  467.             end ;
  468.  
  469.             status.turnTo(dir) ;
  470.             local r = suk() ;
  471.            
  472.             if r then
  473.                 if p.echo then print ('TRUE') end ;
  474.                 if p.echo then print (status.toString()) end ;
  475.             else
  476.                 if p.echo then print ('FALSE') end ;
  477.             end ;
  478.             return r ;
  479.         end ;
  480.    
  481.     elseif op == 'drop' then
  482.         return function(s , count , p)
  483.             if type(s) == 'table' then
  484.                 s , count , p = p , s , count ;
  485.             end ;
  486.             if type(count) == 'table' then
  487.                 s , count , p = s , p , count ;
  488.             end ;
  489.            
  490.             if s ~= nil then
  491.                 turtle.select(s) ;
  492.             end ;
  493.            
  494.             p = workMode.asDefault(p) ;
  495.            
  496.             if p.echo then
  497.                 io.write(string.format('DROP\t%s\t' , dir)) ;
  498.             end
  499.             status.turnTo(dir) ;
  500.             local r = dro(count) ;
  501.             if r then
  502.                 if p.echo then print ('TRUE') end ;
  503.                 if p.echo then print (status.toString()) end ;
  504.             else
  505.                 if p.echo then print ('FALSE') end ;
  506.             end ;
  507.             return r ;
  508.         end ;
  509.     end ;
  510. end ;
  511.  
  512.  
  513. -------------------------------generate base api----------------------
  514.  
  515. slot = {
  516.     first = function(s)
  517.         turtle.select(s) ;
  518.         for i = 1 , s do
  519.             if turtle.compareTo(i) then
  520.                 s = i ;
  521.                 break ;
  522.             end ;
  523.         end ;
  524.         return s ;
  525.     end ;
  526.    
  527.     last = function(s)
  528.         turtle.select(s) ;
  529.         for i = const.slotnum , s , -1 do
  530.             if turtle.compareTo(i) then
  531.                 s = i ;
  532.                 break ;
  533.             end ;
  534.         end ;
  535.         return s ;
  536.     end ;
  537.    
  538.     count = function(s)
  539.         local c = turtle.getItemCount(s) ;
  540.         if c == 0 then return 0 end ;
  541.         turtle.select(s) ;
  542.         for i = s + 1 , const.slotnum do
  543.             if turtle.compareTo(i) then
  544.                 c = c + turtle.getItemCount(i) ;
  545.             end ;
  546.         end ;
  547.         return c ;
  548.     end ;
  549.    
  550.     packUp = function(i)
  551.         -- use items in slots after i to make slot i as full as possible .
  552.        
  553.         count = turtle.getItemCount(i) ;
  554.         space = turtle.getItemSpace(i) ;
  555.         if count ~= 0 and space ~= 0 then
  556.             turtle.select(i) ;
  557.             for j = const.slotnum , i + 1 , -1 do
  558.                 if turtle.compareTo(j) then
  559.                     got = turtle.getItemCount(j) ;
  560.                     turtle.select(j) ;
  561.                     if got >= space then
  562.                         turtle.transferTo(i , space) ;
  563.                         break ;
  564.                     else
  565.                         turtle.transferTo(i , got) ;
  566.                     end ;
  567.                     turtle.select(i) ;
  568.                 end ;
  569.             end ;
  570.         end ;
  571.     end ;
  572.    
  573.     packUpAll = function()
  574.         for i = 1 , const.slotnum do
  575.             slot.packUp(i) ;
  576.         end ;
  577.     end ;
  578.    
  579.     waitingForReloading = function(s , time , amont)
  580.         amont = withDefault(amont , 2) ;
  581.         print (string.format('Please reload slot%d to at least %d in %ds' , s , amont , time)) ;
  582.         local t = 0 ;
  583.         while slot.count(s) < amont do
  584.             sleep(2) ;
  585.             t = t + 1 ;
  586.             if t >= time then
  587.                 forceTryBack(string.format('lack of stuff in slot%d' , s)) ;
  588.             end ;
  589.         end ;
  590.         io.write("Leaving soon ") ;
  591.         for i = 1 , 3 do sleep(2) io.write(".") end ;
  592.         print(" byebye!") ;
  593.         slot.packUp(s) ;
  594.     end ;
  595.    
  596.     checkList = function(list , must)
  597.         must = withDefault(must , #list) ;
  598.         print('Checking List (load them now):') ;
  599.         for s = 1 , #list do
  600.             local part1 = '['..s..']: <'..list[s][1]..'>' ;
  601.             if s > must then
  602.                 part1 = '['..s..']: ['..list[s][1]..']' ;
  603.             end
  604.             local part2 = '' ;
  605.             if #list[s] > 1 then
  606.                 part2 = ' * '..(list[s][2] + 1) ;
  607.             end
  608.             print(part1..part2) ;
  609.         end
  610.         for s = 1 , must do
  611.             local amont = withDefault(list[s][2] , 0) + 1 ;
  612.             local t = 0 ;
  613.             while slot.count(s) < amont do
  614.                 sleep(2) ;
  615.                 t = t + 1 ;
  616.                 if t >= 30 then
  617.                     forceTryBack('lack of <'..list[s][1]..'>') ;
  618.                 end ;
  619.             end ;
  620.         end ;
  621.         io.write("Leaving soon ") ;
  622.         for i = 1 , 6 do sleep(1) io.write(".") end ;
  623.         print(" byebye!") ;
  624.         slot.packUpAll() ;
  625.     end ;
  626.    
  627.     firstnSlots = function(slots)
  628.         if type(slots) == 'number' then
  629.             local s = {} ;
  630.             for i = 1 , slots do
  631.                 if const.needfuel then
  632.                     s[#s + 1] = i + 1 ;
  633.                 else
  634.                     s[#s + 1] = i ;
  635.                 end ;
  636.             end ;
  637.             slots = s ;
  638.         end ;
  639.         return slots ;
  640.     end ;
  641. } ;
  642.  
  643. refuel = function(moves)
  644.     moves = math.max(1 , moves) ;
  645.     if not (turtle.getItemCount(status.slots.fuel) > 1) then
  646.         slot.packUp(status.slots.fuel) ;
  647.     end ;
  648.     while turtle.getFuelLevel() < moves and turtle.getItemCount(status.slots.fuel) > 1 do
  649.         turtle.select(status.slots.fuel) ;
  650.         turtle.refuel(1) ;
  651.     end ;
  652.     if not (turtle.getItemCount(status.slots.fuel) > 1) then
  653.         print("More fuel needed !") ;
  654.         slot.waitingForReloading(status.slots.fuel , 30) ;
  655.     end ;
  656. end ;
  657.  
  658.  
  659. move , place , detect , dig , compare , attack , suck , drop = {} , {} , {} , {} , {} , {} , {} , {} ;
  660. apiFactory = memorized(apiFactory) ;
  661.  
  662. for k , v in pairs(status.innerDirection) do
  663.     move[k] = apiFactory ('move' , v) ;
  664.     place[k] = apiFactory ('place' , v) ;
  665.     detect[k] = apiFactory ('detect' , v) ;
  666.     dig[k] = apiFactory ('dig' , v) ;
  667.     compare[k] = apiFactory ('compare' , v) ;
  668.     attack[k] = apiFactory ('attack' , v) ;
  669.     suck[k] = apiFactory ('suck' , v) ;
  670.     drop[k] = apiFactory ('drop' , v) ;
  671. end ;
  672.  
  673. ------------------------------advanced apis in move---------------------------------
  674.  
  675. move.to = function(dest , p)
  676.     dest.x = withDefault(dest.x , status.pos.x) ;
  677.     dest.y = withDefault(dest.y , status.pos.y) ;
  678.     dest.z = withDefault(dest.z , status.pos.z) ;
  679.  
  680.     local p1 = {destroy = false ; force = false ; tryTime = 0} ;
  681.    
  682.     while status.posDis(dest , status.pos) > 0 do
  683.         local moved = false ;
  684.         for k , v in pairs(status.dif) do
  685.             if status.posDis(dest , status.posAdd(status.pos , v)) < status.posDis(dest , status.pos) then
  686.                 moved = moved or move[k](p1) ;
  687.                 if moved then break end ;
  688.             end ;
  689.         end ;
  690.         if not moved then
  691.             for k , v in pairs(status.dif) do
  692.                 if status.posDis(dest , status.posAdd(status.pos , v)) < status.posDis(dest , status.pos) then
  693.                     moved = moved or move[k](p) ;
  694.                     if moved then break end ;
  695.                 end ;
  696.             end ;
  697.         end ;
  698.     end ;
  699.     return true ;
  700. end ;
  701.  
  702. move.go = function(destv , p)
  703.     return move.to(status.posAdd(status.pos , destv) , p) ;
  704. end ;
  705.  
  706. function forceTryBack(msg)
  707.     print (msg) ;
  708.     move.to({x = 0 , y = 0 , z = 0} , {destroy = true , force = true , tryTime = 10000 , autoRefuel = false , echo = const.debuging}) ;
  709.     status.turnTo('f') ;
  710.     slot.packUpAll() ;
  711.     error(string.format("FORCE BACK: %s" , msg)) ;
  712. end ;
  713.  
  714.  
  715. ------------------------------recursive apis---------------------------------
  716.  
  717. search = function(deep , check , p)
  718.     p = workMode.asDefault(p , true) ;
  719.     p.withStart = withDefault(p.withStart , false) ;
  720.     p.needBack = withDefault(p.needBack , true) ;
  721.     p.allowFail = withDefault(p.allowFail , true) ;
  722.     p.branch = withDefault(p.branch , true) ;
  723.     p.append = withDefault(p.append , function () return true end) ;
  724.    
  725.     local function tryRun (fun , pa)
  726.         if fun ~= nil then fun(unpack(pa)) end ;
  727.     end ;
  728.    
  729.     local startPos = status.pos ;
  730.    
  731.     local function rec (d , dir)
  732.         if d >= deep then
  733.             return p.append(startPos , dir , d) ;
  734.         end
  735.         tryRun (p.beforeArrive , {startPos , dir , d}) ;
  736.         if not move[dir](p) then
  737.             return false ;
  738.         end
  739.         tryRun (p.afterArrive , {startPos , dir , d}) ;
  740.        
  741.         local r = true ;
  742.         local branched = 0 ;
  743.         for i = 0 , 5 do
  744.             local next_dir = status.innerDirection[(status.numberedDirection[dir] + i) % 6] ;
  745.             if check(startPos , next_dir , d) then
  746.                 if p.allowFail or r then
  747.                     if p.branch or branched == 0 then
  748.                         local ri = rec (d + 1 , next_dir) ;
  749.                         if ri then
  750.                             branched = branched + 1 ;
  751.                         end ;
  752.                     end ;
  753.                     r = r and ri ;
  754.                 end ;
  755.             end ;
  756.         end ;
  757.        
  758.         if p.needBack then
  759.             tryRun (p.beforeLeave , {startPos , dir , d}) ;
  760.             if not move[status.negativeDirection[dir]](p) then
  761.                 forceTryBack('failed to backtrack') ;
  762.             end ;
  763.             tryRun (p.afterLeave , {startPos , dir , d}) ;
  764.         end ;
  765.         return r ;
  766.     end ;
  767.    
  768.     local r = true ;
  769.     local branched = 0 ;
  770.     local d = -1 ;
  771.     if p.withStart then
  772.         d = 0 ;
  773.     end ;
  774.     for i = 0 , 5 do
  775.         local next_dir = status.innerDirection[i] ;
  776.         if check(startPos , next_dir , d) then
  777.             if p.allowFail or r then
  778.                 if p.branch or branched == 0 then
  779.                     if p.withStart then
  780.                         tryRun (p.afterArrive , {startPos , next_dir , d}) ;
  781.                     end ;
  782.                     local ri = rec (d + 1 , next_dir) ;
  783.                     if p.withStart then
  784.                         tryRun (p.beforeLeave , {startPos , next_dir , d}) ;
  785.                     end ;
  786.                     if ri then
  787.                         branched = branched + 1 ;
  788.                     end ;
  789.                 end ;
  790.                 r = r and ri ;
  791.             end ;
  792.         end ;
  793.     end ;
  794.     return r ;
  795. end ;
  796.  
  797. --------------------------------link function---------------------------
  798.  
  799. link = function(...)
  800.     local p = deepcopy({...}) ;
  801.     local startPos = status.pos ;
  802.    
  803.     local bind = function(pi , fi , fj)
  804.         local beforeLeave = pi.beforeLeave ;
  805.         pi.beforeLeave = function(searchStartPos , searchDir , searchDeep)
  806.             if pi.linked(searchStartPos , searchDir , searchDeep , startPos) then
  807.                 fj() ;
  808.             end ;
  809.             if beforeLeave ~= nil then
  810.                 beforeLeave(searchStartPos , searchDir , searchDeep) ;
  811.             end ;
  812.             return r ;
  813.         end ;
  814.         return pi ;
  815.     end ;
  816.    
  817.     local f = {} ;
  818.    
  819.     if type(p[#p]) == 'function' then
  820.         f[#p] = p[#p] ; p[#p] = nil ;
  821.     else
  822.         f[#p + 1] = function() return true end ;
  823.     end ;
  824.    
  825.     for k , v in ipairs(p) do
  826.         if not (type(p[k]) == "table") then
  827.             error ("PARAM ERROR: api.link()") ;
  828.         end ;
  829.         f[k] = withParam(search , {p[k].deep , p[k].check , p[k]}) ;
  830.     end ;
  831.    
  832.     for k , v in ipairs(p) do
  833.         p[k] = bind(p[k] , f[k] , f[k + 1]) ;
  834.     end ;
  835.    
  836.     local r = f[1]() ;
  837.     return r ;
  838. end ;
  839.  
  840. --------------------------------user tools---------------------------
  841.  
  842. scan = function (dir , times , p)
  843.     p = workMode.asDefault(p , true) ;
  844.     p.withStart = withDefault(p.withStart , true) ;
  845.     p.step = withDefault(p.step , 1) ;
  846.     p.first = withDefault(p.first , 0) ;
  847.    
  848.     p.deep = p.first + (times - 1) * p.step + 1 ;
  849.     p.branch = false ;
  850.     p.check = function(searchStartPos , searchDir , searchDeep)
  851.         return searchDir == dir ;
  852.     end ;
  853.     p.linked = function (searchStartPos , searchDir , searchDeep , startPos)
  854.         local dis = status.posDis(status.pos , searchStartPos) ;
  855.         return dis >= p.first and ((dis - p.first) % p.step) == 0 ;
  856.     end ;
  857.     return p ;
  858. end ;
  859.  
  860. cycle = function (dir , round , times , p)
  861.     if type(times) == 'table' then
  862.         p , times = times , p
  863.     end ;
  864.     p = workMode.asDefault(p , true) ;
  865.     p.withStart = withDefault(p.withStart , true) ;
  866.     p.first = withDefault(p.first , 0) ;
  867.     p.last = withDefault(p.last , p.first + #round * times - 1) ;
  868.     p.deep = p.last + 1 ;
  869.     p.branch = false ;
  870.     p.check = function(searchStartPos , searchDir , searchDeep)
  871.         return searchDir == dir ;
  872.     end ;
  873.     p.linked = function (searchStartPos , searchDir , searchDeep , startPos)
  874.         local dis = status.posDis(status.pos , searchStartPos) ;
  875.         if type(round) == 'table' then
  876.             return round[dis % #round + 1] > 0 ;
  877.         else
  878.             local c = string.char(string.byte(round , dis % #round + 1)) ;
  879.             return c ~= ' ' and c ~= '#' ;
  880.         end ;
  881.     end ;
  882.     return p ;
  883. end ;
  884.  
  885. go = function (x , y , z , p)
  886.     local destv = false ;
  887.     if type(x) == 'table' then
  888.         destv , p = x , y ;
  889.     else
  890.         destv = pos(x , y , z) ;
  891.     end ;
  892.     p = workMode.asDefault(p , true) ;
  893.     p.withStart = true ;
  894.     p.deep = 0 ;
  895.     p.branch = false ;
  896.     p.afterArrive = function()
  897.         move.go(destv , p) ;
  898.     end ;
  899.     p.beforeLeave = function(searchStartPos)
  900.         move.to(searchStartPos) ;
  901.     end ;
  902.     p.check = function() return true end ;
  903.     p.linked = function() return true end ;
  904.     return p ;
  905. end ;
  906.  
  907. digLine = function (dir , maxdis , p)
  908.     p = workMode.asDefault(p , {destroy = true}) ;
  909.     p.withStart = withDefault(p.withStart , true) ;
  910.    
  911.     p.deep = withDefault(maxdis , 100) ;
  912.     p.branch = false ;
  913.     p.check = function(searchStartPos , searchDir , searchDeep)
  914.         if searchDir ~= dir then return false end ;
  915.         if detect[searchDir]() then
  916.             dig[searchDir]() ;
  917.             return searchDeep + 1 < r.deep ;
  918.         end ;
  919.         return false ;
  920.     end ;
  921.     p.linked = function (searchStartPos , searchDir , searchDeep , startPos)
  922.         return false ;
  923.     end ;
  924.     return p ;
  925. end ;
  926.  
  927. digAll = function (slots , maxdis , p)
  928.     p = workMode.asDefault(p , {destroy = true}) ;
  929.     p.withStart = withDefault(p.withStart , true) ;
  930.     local tmp = slot.firstnSlots(slots) ;
  931.     slots = tmp ;
  932.    
  933.     p.deep = withDefault(maxdis , 100) ;
  934.     p.branch = true ;
  935.     p.check = function(searchStartPos , searchDir , searchDeep)
  936.         for k , v in ipairs(slots) do
  937.             if compare[searchDir](v) then
  938.                 dig[searchDir]() ;
  939.                 return searchDeep + 1 < p.deep ;
  940.             end ;
  941.         end ;
  942.         return false ;
  943.     end ;
  944.     p.linked = function (searchStartPos , searchDir , searchDeep , startPos)
  945.         return false ;
  946.     end ;
  947.     return p ;
  948. end ;
  949.  
  950. digExcept = function (slots , maxdis , p)
  951.     local tmp = slot.firstnSlots(slots) ;
  952.     slots = tmp ;
  953.    
  954.     local r = digAll(slots , maxdis , p) ;
  955.     r.check = function(searchStartPos , searchDir , searchDeep)
  956.         if detect[searchDir]() then
  957.             for k , v in ipairs(slots) do
  958.                 if compare[searchDir](v) then
  959.                     return false ;
  960.                 end ;
  961.             end ;
  962.             dig[searchDir]() ;
  963.             return searchDeep + 1 < r.deep ;
  964.         else
  965.             return false ;
  966.         end ;
  967.     end ;
  968.     return r ;
  969. end ;
  970.  
  971. pos = function(a , b , c)
  972.     return {x = a , y = b , z = c} ;
  973. end ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement