Advertisement
Guest User

Sphere Maker v2 - ComputerCraft

a guest
Mar 12th, 2013
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.37 KB | None | 0 0
  1. -- Dome and sphere builder.
  2. -- Created by Timothy Goddard
  3. -- Copyright (C) 2012
  4. -- Modified by Mark Sherwood
  5. --
  6. -- Permission is hereby granted, free of charge, to any person obtaining a copy of
  7. -- this software and associated documentation files (the "Software"), to deal in
  8. -- the Software without restriction, including without limitation the rights to
  9. -- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10. -- the Software, and to permit persons to whom the Software is furnished to do so,
  11. -- subject to the following conditions:
  12. --
  13. -- The above copyright notice and this permission notice shall be included in all
  14. -- copies or substantial portions of the Software.
  15. --
  16. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18. -- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19. -- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20. -- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. -- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. --
  23. -- usage: sdbuild <type> <radius> [-c]
  24. -- type should be either dome or sphere
  25. -- radius is distance from centre - total width is actually 2 * radius + 1
  26. -- the structure will be built with its lowest point on the level the turtle is at
  27. -- the block the turtle starts on will be the horizontal centre
  28. -- if -c is passed, will only calculate number of blocks required and not build
  29. -- Building blocks can be placed in slots 1 - 15, fuel in slot 16
  30.  
  31. local arg = { ... }
  32.  
  33. buildType = arg[1]
  34. radius = tonumber(arg[2])
  35.  
  36. cost_only = false
  37. blocks = 0
  38. cslot = 1
  39. if arg[3] == "-c" then
  40.   cost_only = true
  41. end
  42.  
  43. -- Navigation features
  44. -- allow the turtle to move while tracking its position
  45. -- this allows us to just give a destination point and have it go there
  46.  
  47. positionx = radius
  48. positiony = radius
  49. facing = 0
  50.  
  51. function turnRightTrack()
  52.   turtle.turnRight()
  53.   facing = facing + 1
  54.   if facing >= 4 then
  55.     facing = 0
  56.   end
  57. end
  58.  
  59. function turnLeftTrack()
  60.   turtle.turnLeft()
  61.   facing = facing - 1
  62.   if facing < 0 then
  63.     facing = 3
  64.   end
  65. end
  66.  
  67. function checkFuel()
  68.   success = false
  69.   while not success do
  70.     if turtle.getFuelLevel() < 2 then
  71.       turtle.select(16)
  72.       success = turtle.refuel(2)
  73.       turtle.select(cslot)
  74.     else
  75.       success = true
  76.     end
  77.     if not success then
  78.         print("No fuel in slot 16.")
  79.         print("Please add fuel and press enter to continue.")
  80.         io.read()
  81.     end
  82.   end
  83. end
  84.  
  85. function safeForward()
  86.   checkFuel()
  87.   success = false
  88.   while not success do
  89.     success = turtle.forward()
  90.     if not success then
  91.       print("Blocked attempting to move forward.")
  92.       print("Please clear and press enter to continue.")
  93.       io.read()
  94.     end
  95.   end
  96. end
  97.  
  98. function safeBack()
  99.   checkFuel()
  100.   success = false
  101.   while not success do
  102.     success = turtle.back()
  103.     if not success then
  104.       print("Blocked attempting to move back.")
  105.       print("Please clear and press enter to continue.")
  106.       io.read()
  107.     end
  108.   end
  109. end
  110.  
  111. function safeUp()
  112.   checkFuel()
  113.   success = false
  114.   while not success do
  115.     success = turtle.up()
  116.     if not success then
  117.       print("Blocked attempting to move up.")
  118.       print("Please clear and press enter to continue.")
  119.       io.read()
  120.     end
  121.   end
  122. end
  123.  
  124. function moveY(targety)
  125.   if targety == positiony then
  126.     return
  127.   end
  128.  
  129.   if (facing ~= 0 and facing ~= 2) then -- check axis
  130.     turnRightTrack()
  131.   end
  132.  
  133.   while targety > positiony do
  134.     if facing == 0 then
  135.       safeForward()
  136.     else
  137.       safeBack()
  138.     end
  139.     positiony = positiony + 1
  140.   end
  141.  
  142.   while targety < positiony do
  143.     if facing == 2 then
  144.       safeForward()
  145.     else
  146.       safeBack()
  147.     end
  148.     positiony = positiony - 1
  149.   end
  150. end
  151.  
  152. function moveX(targetx)
  153.   if targetx == positionx then
  154.     return
  155.   end
  156.  
  157.   if (facing ~= 1 and facing ~= 3) then -- check axis
  158.     turnRightTrack()
  159.   end
  160.  
  161.   while targetx > positionx do
  162.     if facing == 1 then
  163.       safeForward()
  164.     else
  165.       safeBack()
  166.     end
  167.     positionx = positionx + 1
  168.   end
  169.  
  170.   while targetx < positionx do
  171.     if facing == 3 then
  172.       safeForward()
  173.     else
  174.       safeBack()
  175.     end
  176.     positionx = positionx - 1
  177.   end
  178. end
  179.  
  180. function navigateTo(targetx, targety)
  181.   -- Cost calculation mode - don't move
  182.   if cost_only then
  183.     return
  184.   end
  185.  
  186.   if facing == 0 or facing == 2 then -- Y axis
  187.     moveY(targety)
  188.     moveX(targetx)
  189.   else
  190.     moveX(targetx)
  191.     moveY(targety)
  192.   end
  193. end
  194.  
  195. function placeBlock()
  196.   -- Cost calculation mode - don't move
  197.   blocks = blocks + 1
  198.   if cost_only then
  199.     return
  200.   end
  201.  
  202.   if turtle.getItemCount(cslot) == 0 then
  203.     foundSlot = false
  204.     while not foundSlot do
  205.       for i = 1,15 do
  206.         if turtle.getItemCount(i) > 0 then
  207.           foundSlot = i
  208.           break
  209.         end
  210.       end
  211.       if not foundSlot then
  212.         -- No resources
  213.         print("Out of building materials. Please refill and press enter to continue.")
  214.         io.read()
  215.       end
  216.     end
  217.     cslot = foundSlot
  218.     turtle.select(foundSlot)
  219.   end
  220.  
  221.   turtle.placeDown()
  222. end
  223.  
  224. -- Main dome and sphere building routine
  225.  
  226. width = radius * 2 + 1
  227. sqrt3 = 3 ^ 0.5
  228. boundary_radius = radius + 1.0
  229. boundary2 = boundary_radius ^ 2
  230.  
  231. if buildType == "dome" then
  232.   zstart = radius
  233. elseif buildType == "sphere" then
  234.   zstart = 0
  235. else
  236.   print("Usage: sdbuild <shape> <radius> [-c]")
  237.   os.exit(1)
  238. end
  239. zend = width - 1
  240.  
  241. -- This loop is for each vertical layer through the sphere or dome.
  242. for z = zstart,zend do
  243.   if not cost_only then
  244.     safeUp()
  245.   end
  246.   print("Layer " .. z)
  247.   cz2 = (radius - z) ^ 2
  248.  
  249.   limit_offset_y = (boundary2 - cz2) ^ 0.5
  250.   max_offset_y = math.ceil(limit_offset_y)
  251.  
  252.   -- We do first the +x side, then the -x side to make movement efficient
  253.   for side = 0,1 do
  254.     -- On the right we go from small y to large y, on the left reversed
  255.     -- This makes us travel clockwise around each layer
  256.     if (side == 0) then
  257.       ystart = radius - max_offset_y
  258.       yend = radius + max_offset_y
  259.       ystep = 1
  260.     else
  261.       ystart = radius + max_offset_y
  262.       yend = radius - max_offset_y
  263.       ystep = -1
  264.     end
  265.    
  266.     for y = ystart,yend,ystep do
  267.       cy2 = (radius - y) ^ 2
  268.      
  269.       remainder2 = (boundary2 - cz2 - cy2)
  270.      
  271.      
  272.       if remainder2 >= 0 then
  273.         -- This is the maximum difference in x from the centre we can be without definitely being outside the radius
  274.         max_offset_x = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
  275.        
  276.         -- Only do either the +x or -x side
  277.         if (side == 0) then
  278.           -- +x side
  279.           xstart = radius
  280.           xend = radius + max_offset_x
  281.         else
  282.           -- -x side
  283.           xstart = radius - max_offset_x
  284.           xend = radius - 1
  285.         end
  286.        
  287.         -- Reverse direction we traverse xs when in -y side
  288.         if y > radius then
  289.           temp = xstart
  290.           xstart = xend
  291.           xend = temp
  292.           xstep = -1
  293.         else
  294.           xstep = 1
  295.         end
  296.        
  297.         for x = xstart,xend,xstep do
  298.           cx2 = (radius - x) ^ 2
  299.           distance_to_centre = (cx2 + cy2 + cz2) ^ 0.5
  300.           -- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
  301.           if distance_to_centre < boundary_radius and distance_to_centre + sqrt3 >= boundary_radius then
  302.             offsets = {{0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}
  303.             for i=1,6 do
  304.               offset = offsets[i]
  305.               dx = offset[1]
  306.               dy = offset[2]
  307.               dz = offset[3]
  308.               if ((radius - (x + dx)) ^ 2 + (radius - (y + dy)) ^ 2 + (radius - (z + dz)) ^ 2) ^ 0.5 >= boundary_radius then
  309.                 -- This is a point to use
  310.                 navigateTo(x, y)
  311.                 placeBlock()
  312.                 break
  313.               end
  314.             end
  315.           end
  316.         end
  317.       end
  318.     end
  319.   end
  320. end
  321.  
  322. -- Return to where we started in x,y place and turn to face original direction
  323. -- Don't change vertical place though - should be solid under us!
  324. navigateTo(radius, radius)
  325. while (facing > 0) do
  326.   turnLeftTrack()
  327. end
  328.  
  329. print("Blocks used: " .. blocks)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement