Guest User

Untitled

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