Advertisement
lambdaCraft

mc-puppet2

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