Tribble1991

Untitled

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