Advertisement
heimdall116

Untitled

Aug 24th, 2014
367
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.86 KB | None | 0 0
  1. --[[
  2.     Heimdall116, August 2014
  3.    
  4.     1) Stole several functions from dan200's tunneling routine
  5.          to provide consistent turtle operation.
  6.     2) Bresenham circle algorithm adapted from C# code on Wikipedia.
  7.     3) Thanks to computercraft.info forums for help with nesting tables.
  8.     4) Efficient pathing method inspired by demonpants (
  9.     5) Remaining code is original, and is now public domain.
  10.    
  11.     M Glow Blue.
  12. ]]--
  13.  
  14. local tArgs = { ... }
  15. if #tArgs ~= 1 then
  16.     print( "Usage: dome <radius>" )
  17.     return
  18. end
  19.  
  20. -- Read in the radius
  21. local radius = tonumber( tArgs[1] )
  22. if radius < 1 then
  23.     print( "Radius must be positive" )
  24.     return
  25. end
  26.  
  27. local depth = 0
  28. local collected = 0
  29. local facing = 1
  30. local xRel = 0
  31. local yRel = 0
  32.  
  33. local function collect() -- Modified to constantly drop all junk
  34.     for i=1,9 do
  35.         if turtle.getItemCount(i) == 1 then turtle.drop(i) end
  36.     end
  37.     --collected = collected + 1
  38.     --if math.fmod(collected, 25) == 0 then
  39.     --  print( "Mined "..collected.." items." )
  40.     --end
  41. end
  42.  
  43. local function tryDig()
  44.     while turtle.detect() do
  45.         if turtle.dig() then
  46.             collect()
  47.             sleep(0.5)
  48.         else
  49.             return false
  50.         end
  51.     end
  52.     return true
  53. end
  54.  
  55. local function tryDigUp()
  56.     while turtle.detectUp() do
  57.         if turtle.digUp() then
  58.             collect()
  59.             sleep(0.5)
  60.         else
  61.             return false
  62.         end
  63.     end
  64.     return true
  65. end
  66.  
  67. local function tryDigDown()
  68.     while turtle.detectDown() do
  69.         if turtle.digDown() then
  70.             collect()
  71.             sleep(0.5)
  72.         else
  73.             return false
  74.         end
  75.     end
  76.     return true
  77. end
  78.  
  79. local function refuel()
  80.     local fuelLevel = turtle.getFuelLevel()
  81.     if fuelLevel == "unlimited" or fuelLevel > 0 then
  82.         return
  83.     end
  84.    
  85.     local function tryRefuel()
  86.         for n=1,16 do
  87.             if turtle.getItemCount(n) > 0 then
  88.                 turtle.select(n)
  89.                 if turtle.refuel(1) then
  90.                     turtle.select(1)
  91.                     return true
  92.                 end
  93.             end
  94.         end
  95.         turtle.select(1)
  96.         return false
  97.     end
  98.    
  99.     if not tryRefuel() then
  100.         print( "Add more fuel to continue." )
  101.         while not tryRefuel() do
  102.             sleep(1)
  103.         end
  104.         print( "Resuming Tunnel." )
  105.     end
  106. end
  107.  
  108. local function tryUp()
  109.     refuel()
  110.     while not turtle.up() do
  111.         if turtle.detectUp() then
  112.             if not tryDigUp() then
  113.                 return false
  114.             end
  115.         elseif turtle.attackUp() then
  116.             collect()
  117.         else
  118.             sleep( 0.5 )
  119.         end
  120.     end
  121.     return true
  122. end
  123.  
  124. local function tryDown()
  125.     refuel()
  126.     while not turtle.down() do
  127.         if turtle.detectDown() then
  128.             if not tryDigDown() then
  129.                 return false
  130.             end
  131.         elseif turtle.attackDown() then
  132.             collect()
  133.         else
  134.             sleep( 0.5 )
  135.         end
  136.     end
  137.     return true
  138. end
  139.  
  140. local function tryForward()
  141.     refuel()
  142.     while not turtle.forward() do
  143.         if turtle.detect() then
  144.             if not tryDig() then
  145.                 return false
  146.             end
  147.         elseif turtle.attack() then
  148.             collect()
  149.         else
  150.             sleep( 0.5 )
  151.         end
  152.     end
  153.     return true
  154. end
  155.  
  156. local function tryPlaceDown() -- Added by Heimdall116
  157.         if turtle.detectDown() then return true
  158.         elseif not turtle.placeDown() then
  159.             if turtle.attackDown() then
  160.                 collect()
  161.                 sleep(0.5)
  162.                 return turtle.placeDown()
  163.             else
  164.                 for i=1,9 do
  165.                     if turtle.getItemCount(i) > 0 then
  166.                         turtle.select(i)
  167.                         print('Selecting ',i)
  168.                         return turtle.placeDown()
  169.                     end
  170.                 end
  171.             end
  172.         end
  173.     return true
  174. end
  175.  
  176. local function round(q)
  177.     if q == 0 then return 0 end
  178.     local a = 1
  179.     if q < 0 then a = -1 end
  180.     b = math.abs(q)
  181.    
  182.     if b-math.floor(b) < .5 then
  183.         return math.floor(b) * a
  184.     else
  185.         return math.ceil(b) * a
  186.     end
  187. end
  188.  
  189. local function face(f)
  190. -- Re-orient the turtle WRT original facing: 1=forward; 2=right; 3=back; 4=left
  191.     if f-facing == 0 then return
  192.     elseif math.abs(f-facing) == 2 or f-facing == 1 or f-facing == -3 then
  193.         while f-facing ~= 0 do
  194.             turtle.turnRight()
  195.             facing = facing + 1
  196.             if facing == 5 then facing = 1 end
  197.         end
  198.     else
  199.         turtle.turnLeft()
  200.         facing = facing - 1
  201.         if facing == 0 then facing = 4 end
  202.     end
  203. end
  204.  
  205. local function getThereX(dist)
  206.     if dist == 0 then
  207.         return
  208.     elseif dist > 0 then
  209.         face(1)
  210.     else
  211.         face(3)
  212.     end
  213.    
  214.     for n = 1,math.abs(dist) do
  215.         tryDig()
  216.         tryForward()
  217.     end
  218.    
  219.     xRel = xRel + dist
  220.     return 0
  221. end
  222.  
  223. local function getThereY(dist)
  224.     if dist == 0 then
  225.         return
  226.     elseif dist > 0 then
  227.         face(4)
  228.     else
  229.         face(2)
  230.     end
  231.    
  232.     for n = 1,math.abs(dist) do
  233.         tryDig()
  234.         tryForward()
  235.     end
  236.    
  237.     yRel = yRel + dist
  238.     return 0
  239. end
  240.  
  241. local function goTo(x2,y2)
  242.     local dx = round(x2-xRel)
  243.     local dy = round(y2-yRel)
  244.    
  245.     -- Check for low-hanging fruit first
  246.     if facing == 1 and dx > 0 then
  247.         dx = getThereX(dx)
  248.     elseif facing == 2 and dy < 0 then
  249.         dy = getThereY(dy)
  250.     elseif facing == 3 and dx < 0 then
  251.         dx = getThereX(dx)
  252.     elseif facing == 4 and dy > 0 then
  253.         dy = getThereY(dy)
  254.     end
  255.    
  256.     -- do the shorter angle next
  257.     if facing % 2 == 1 then
  258.         dy = getThereY(dy)
  259.         dx = getThereX(dx)
  260.     else
  261.         dx = getThereX(dx)
  262.         dy = getThereY(dy)
  263.     end
  264. end
  265.  
  266. print( "Building dome..." )
  267.  
  268. for h=1,radius do
  269.     -- r is the "local" radius for height "h"
  270.     local r = round(radius * math.cos((h-1)/radius * math.pi/2))
  271.     --local r = radius
  272.     --print('r='..r)
  273.     tryDigUp()
  274.     turtle.up()
  275.    
  276.     -- Bresenham's circle algorithm, adapted
  277.     -- from Wikipedia 8/25/14  
  278.     local x0 = radius
  279.     local y0 = 0
  280.     local x = r
  281.     local y = 0
  282.     local rErr = 1-x
  283.    
  284.     local points = {}
  285.     while x >= y do
  286.        
  287.     --[[ use theta to sort ordered pairs for efficient turtle
  288.          motion.  Thanks to hilburn on computercraft.info forums
  289.          for helping me nest these tables... ]]--
  290.        
  291.         --local x1 = 0
  292.         --local y1 = 0
  293.         --local t1 = 0
  294.         --local r1 = 0
  295.        
  296.         points[#points+1] = { ['x']= x+x0, ['y']= y+y0, ['theta']=math.atan2( x+x0, y+y0) }
  297.         points[#points+1] = { ['x']= y+x0, ['y']= x+y0, ['theta']=math.atan2( y+x0, x+y0) }
  298.         points[#points+1] = { ['x']=-x+x0, ['y']= y+y0, ['theta']=math.atan2(-x+x0, y+y0) }
  299.         points[#points+1] = { ['x']=-y+x0, ['y']= x+y0, ['theta']=math.atan2(-y+x0, x+y0) }
  300.         points[#points+1] = { ['x']=-x+x0, ['y']=-y+y0, ['theta']=math.atan2(-x+x0,-y+y0) }
  301.         points[#points+1] = { ['x']=-y+x0, ['y']=-x+y0, ['theta']=math.atan2(-y+x0,-x+y0) }
  302.         points[#points+1] = { ['x']= x+x0, ['y']=-y+y0, ['theta']=math.atan2( x+x0,-y+y0) }
  303.         points[#points+1] = { ['x']= y+x0, ['y']=-x+y0, ['theta']=math.atan2( y+x0,-x+y0) }
  304.        
  305.         y=y+1
  306.         if rErr < 0 then
  307.             rErr = rErr+2*y+1
  308.         else
  309.             x=x-1
  310.             rErr = rErr+2*(y-x+1)
  311.         end
  312.     end
  313.    
  314.     -- Calculate theta
  315.     --for i=1,#points do
  316.     --  if points[i].x <= 0 and points[i].y >= 0 then
  317.     --      points[i].theta = math.acos(r/math.sqrt(points[i].x^2+points[i].y^2))
  318.     -- 
  319.     --  elseif points[i].x >= 0 and points[i].y >= 0 then
  320.     --      points[i].theta = math.pi/2 + math.acos(r/math.sqrt(points[i].x^2+points[i].y^2))
  321.     -- 
  322.     --  elseif points[i].x >= 0 and points[i].y <= 0 then
  323.     --      points[i].theta = 3*math.pi/2 + math.acos(r/math.sqrt(points[i].x^2+points[i].y^2))
  324.     -- 
  325.     --  elseif points[i].x <= 0 and points[i].y <= 0 then
  326.     --      points[i].theta = 3*math.pi/2 + math.acos(r/math.sqrt(points[i].x^2+points[i].y^2))
  327.     -- 
  328.     --  else
  329.     --      print('Invalid theta: x=',points.i.x,', y=',points.i.y,', theta=',theta)
  330.     --  end
  331.     --end
  332.    
  333.     table.sort(points, function(p1,p2) return p1.theta<p2.theta end)
  334.    
  335.     -- method blatantly stolen from demonpants.
  336.     for i = 1, #points - 1 do
  337.         local c = i + 1
  338.         local minDist = math.abs(points[c].x-points[i].x) + math.abs(points[c].y-points[i].y)
  339.        
  340.         for j = i+2, #points - 1 do
  341.             local dist = math.abs(points[j].x-points[i].x) + math.abs(points[j].y-points[i].y)
  342.             if dist < minDist then
  343.                 c = j
  344.                 minDist = dist
  345.             end
  346.         end
  347.         swap = points[i+1].x
  348.         points[i+1].x = points[c].x
  349.         points[c].x = swap
  350.         swap = points[i+1].y
  351.         points[i+1].y = points[c].y
  352.         points[c].y = swap
  353.     end
  354.    
  355.     for i=1,#points do
  356.         --print('x=',points[i].x,', y=',points[i].y,', theta=',points[i].theta)
  357.         goTo(points[i].x,points[i].y)
  358.         if not tryPlaceDown() then
  359.             print('Failed at x=',points[i].x,', y=',points[i].y,', theta=',points[i].theta)
  360.             return
  361.         end
  362.     end
  363. end
  364.  
  365. print( "Work complete..." )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement