Advertisement
kilovirus

Untitled

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