NosePicker5555

Untitled

Jan 9th, 2013
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.30 KB | None | 0 0
  1.  
  2. local arg = { ... }
  3.  
  4. type = arg[1]
  5. radius = tonumber(arg[2])
  6.  
  7. cost_only = false
  8. blocks = 0
  9. if arg[3] == "-c" then
  10. cost_only = true
  11. end
  12.  
  13. -- Navigation features
  14. -- allow the turtle to move while tracking its position
  15. -- this allows us to just give a destination point and have it go there
  16.  
  17. positionx = radius
  18. positiony = radius
  19. facing = 0
  20.  
  21. function turnRightTrack()
  22. turtle.turnRight()
  23. facing = facing + 1
  24. if facing >= 4 then
  25. facing = 0
  26. end
  27. end
  28.  
  29. function turnLeftTrack()
  30. turtle.turnLeft()
  31. facing = facing - 1
  32. if facing < 0 then
  33. facing = 3
  34. end
  35. end
  36.  
  37. function safeForward()
  38. success = false
  39. while not success do
  40. success = turtle.forward()
  41. if not success then
  42. print("Blocked attempting to move forward.")
  43. print("Please clear and press enter to continue.")
  44. io.read()
  45. end
  46. end
  47. end
  48.  
  49. function safeBack()
  50. success = false
  51. while not success do
  52. success = turtle.back()
  53. if not success then
  54. print("Blocked attempting to move back.")
  55. print("Please clear and press enter to continue.")
  56. io.read()
  57. end
  58. end
  59. end
  60.  
  61. function safeUp()
  62. success = false
  63. while not success do
  64. success = turtle.up()
  65. if not success then
  66. print("Blocked attempting to move up.")
  67. print("Please clear and press enter to continue.")
  68. io.read()
  69. end
  70. end
  71. end
  72.  
  73. function moveY(targety)
  74. if targety == positiony then
  75. return
  76. end
  77.  
  78. if (facing ~= 0 and facing ~= 2) then -- check axis
  79. turnRightTrack()
  80. end
  81.  
  82. while targety > positiony do
  83. if facing == 0 then
  84. safeForward()
  85. else
  86. safeBack()
  87. end
  88. positiony = positiony + 1
  89. end
  90.  
  91. while targety < positiony do
  92. if facing == 2 then
  93. safeForward()
  94. else
  95. safeBack()
  96. end
  97. positiony = positiony - 1
  98. end
  99. end
  100.  
  101. function moveX(targetx)
  102. if targetx == positionx then
  103. return
  104. end
  105.  
  106. if (facing ~= 1 and facing ~= 3) then -- check axis
  107. turnRightTrack()
  108. end
  109.  
  110. while targetx > positionx do
  111. if facing == 1 then
  112. safeForward()
  113. else
  114. safeBack()
  115. end
  116. positionx = positionx + 1
  117. end
  118.  
  119. while targetx < positionx do
  120. if facing == 3 then
  121. safeForward()
  122. else
  123. safeBack()
  124. end
  125. positionx = positionx - 1
  126. end
  127. end
  128.  
  129. function navigateTo(targetx, targety)
  130. -- Cost calculation mode - don't move
  131. if cost_only then
  132. return
  133. end
  134.  
  135. if facing == 0 or facing == 2 then -- Y axis
  136. moveY(targety)
  137. moveX(targetx)
  138. else
  139. moveX(targetx)
  140. moveY(targety)
  141. end
  142. end
  143.  
  144. cslot = 1
  145. function placeBlock()
  146. -- Cost calculation mode - don't move
  147. blocks = blocks + 1
  148. if cost_only then
  149. return
  150. end
  151.  
  152. if turtle.getItemCount(cslot) == 0 then
  153. foundSlot = false
  154. while not foundSlot do
  155. for i = 1,9 do
  156. if turtle.getItemCount(i) > 0 then
  157. foundSlot = i
  158. break
  159. end
  160. end
  161. if not foundSlot then
  162. -- No resources
  163. print("Out of building materials. Please refill and press enter to continue.")
  164. io.read()
  165. end
  166. end
  167. cslot = foundSlot
  168. turtle.select(foundSlot)
  169. end
  170.  
  171. turtle.placeDown()
  172. end
  173.  
  174. -- Main dome and sphere building routine
  175.  
  176. width = radius * 2 + 1
  177. sqrt3 = 3 ^ 0.5
  178. boundary_radius = radius + 1.0
  179. boundary2 = boundary_radius ^ 2
  180.  
  181. if type == "dome" then
  182. zstart = radius
  183. elseif type == "sphere" then
  184. zstart = 0
  185. else
  186. print("Usage: sdbuild <shape> <radius> [-c]")
  187. os.exit(1)
  188. end
  189. zend = width - 1
  190.  
  191. -- This loop is for each vertical layer through the sphere or dome.
  192. for z = zstart,zend do
  193. if not cost_only then
  194. safeUp()
  195. end
  196. print("Layer " .. z)
  197. cz2 = (radius - z) ^ 2
  198.  
  199. limit_offset_y = (boundary2 - cz2) ^ 0.5
  200. max_offset_y = math.ceil(limit_offset_y)
  201.  
  202. -- We do first the +x side, then the -x side to make movement efficient
  203. for side = 0,1 do
  204. -- On the right we go from small y to large y, on the left reversed
  205. -- This makes us travel clockwise around each layer
  206. if (side == 0) then
  207. ystart = radius - max_offset_y
  208. yend = radius + max_offset_y
  209. ystep = 1
  210. else
  211. ystart = radius + max_offset_y
  212. yend = radius - max_offset_y
  213. ystep = -1
  214. end
  215.  
  216. for y = ystart,yend,ystep do
  217. cy2 = (radius - y) ^ 2
  218.  
  219. remainder2 = (boundary2 - cz2 - cy2)
  220.  
  221.  
  222. if remainder2 >= 0 then
  223. -- This is the maximum difference in x from the centre we can be without definitely being outside the radius
  224. max_offset_x = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
  225.  
  226. -- Only do either the +x or -x side
  227. if (side == 0) then
  228. -- +x side
  229. xstart = radius
  230. xend = radius + max_offset_x
  231. else
  232. -- -x side
  233. xstart = radius - max_offset_x
  234. xend = radius - 1
  235. end
  236.  
  237. -- Reverse direction we traverse xs when in -y side
  238. if y > radius then
  239. temp = xstart
  240. xstart = xend
  241. xend = temp
  242. xstep = -1
  243. else
  244. xstep = 1
  245. end
  246.  
  247. for x = xstart,xend,xstep do
  248. cx2 = (radius - x) ^ 2
  249. distance_to_centre = (cx2 + cy2 + cz2) ^ 0.5
  250. -- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
  251. if distance_to_centre < boundary_radius and distance_to_centre + sqrt3 >= boundary_radius then
  252. offsets = {{0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}
  253. for i=1,6 do
  254. offset = offsets[i]
  255. dx = offset[1]
  256. dy = offset[2]
  257. dz = offset[3]
  258. if ((radius - (x + dx)) ^ 2 + (radius - (y + dy)) ^ 2 + (radius - (z + dz)) ^ 2) ^ 0.5 >= boundary_radius then
  259. -- This is a point to use
  260. navigateTo(x, y)
  261. placeBlock()
  262. break
  263. end
  264. end
  265. end
  266. end
  267. end
  268. end
  269. end
  270. end
  271.  
  272. -- Return to where we started in x,y place and turn to face original direction
  273. -- Don't change vertical place though - should be solid under us!
  274. navigateTo(radius, radius)
  275. while (facing > 0) do
  276. turnLeftTrack()
  277. end
  278.  
  279. print("Blocks used: " .. blocks)
Add Comment
Please, Sign In to add comment