Advertisement
Aeolun

Shape Maker

Jan 31st, 2013
8,175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.60 KB | None | 0 0
  1. cost_only = false
  2. blocks = 0
  3. fuel = 0
  4.  
  5. positionx = 0
  6. positiony = 0
  7. facing = 0
  8.  
  9. function writeOut(message)
  10.     print(message)
  11. end
  12. function checkResources()
  13.     while turtle.getItemCount(activeslot) <= 0 do
  14.         if activeslot == 16 then
  15.             writeOut("Turtle is empty, please put building block in slots and press enter to continue")
  16.             io.read()
  17.             activeslot = 1
  18.             turtle.select(activeslot)
  19.         else
  20.             activeslot = activeslot+1
  21.             writeOut("Turtle slot empty, trying slot "..activeslot)
  22.             turtle.select(activeslot)
  23.         end
  24.         os.sleep(0.2)
  25.     end
  26. end
  27. function checkFuel()
  28.     while turtle.getFuelLevel() < 50 do
  29.         writeOut("Turtle almost out of fuel, pausing. Please drop fuel in inventory. And press enter.")
  30.         io.read()
  31.         turtle.refuel()
  32.     end
  33. end
  34. function placeBlock()
  35.     -- Cost calculation mode - don't move
  36.     blocks = blocks + 1
  37.     if cost_only then
  38.         return
  39.     end
  40.  
  41.     if turtle.detectDown() and not turtle.compareDown() then
  42.         turtle.digDown()
  43.     end
  44.  
  45.     checkResources()
  46.  
  47.     turtle.placeDown()
  48. end
  49. -- Navigation features
  50. -- allow the turtle to move while tracking its position
  51. -- this allows us to just give a destination point and have it go there
  52.  
  53. function turnRightTrack()
  54.     if cost_only then
  55.         return
  56.     end
  57.  
  58.     turtle.turnRight()
  59.     facing = facing + 1
  60.     if facing >= 4 then
  61.         facing = 0
  62.     end
  63. end
  64.  
  65. function turnLeftTrack()
  66.     if cost_only then
  67.         return
  68.     end
  69.  
  70.     turtle.turnLeft()
  71.     facing = facing - 1
  72.     if facing < 0 then
  73.         facing = 3
  74.     end
  75. end
  76. function turnAroundTrack()
  77.     turnLeftTrack()
  78.     turnLeftTrack()
  79. end
  80. function safeForward()
  81.     fuel = fuel + 1
  82.     if cost_only then
  83.         return
  84.     end
  85.  
  86.     checkFuel()
  87.     success = false
  88.     while not success do
  89.         success = turtle.forward()
  90.         if not success then
  91.             while turtle.detect() do
  92.                 if not turtle.dig() then
  93.                     print("Blocked attempting to move forward.")
  94.                     print("Please clear and press enter to continue.")
  95.                     io.read()
  96.                 end
  97.             end
  98.         end
  99.     end
  100. end
  101.  
  102. function safeBack()
  103.     fuel = fuel + 1
  104.     if cost_only then
  105.         return
  106.     end
  107.  
  108.     checkFuel()
  109.     success = false
  110.     while not success do
  111.         success = turtle.back()
  112.         if not success then
  113.             turnAroundTrack();
  114.             while turtle.detect() do
  115.                 if not turtle.dig() then
  116.                     break;
  117.                 end
  118.             end
  119.             turnAroundTrack()
  120.             success = turtle.back()
  121.             if not success then
  122.                 print("Blocked attempting to move back.")
  123.                 print("Please clear and press enter to continue.")
  124.                 io.read()
  125.             end
  126.         end
  127.     end
  128. end
  129.  
  130. function safeUp()
  131.     fuel = fuel + 1
  132.     if cost_only then
  133.         return
  134.     end
  135.  
  136.     checkFuel()
  137.     success = false
  138.     while not success do
  139.         success = turtle.up()
  140.         if not success then
  141.             while turtle.detectUp() do
  142.                 if not turtle.digUp() then
  143.                     print("Blocked attempting to move up.")
  144.                     print("Please clear and press enter to continue.")
  145.                     io.read()
  146.                 end
  147.             end
  148.         end
  149.     end
  150. end
  151.  
  152. function safeDown()
  153.     fuel = fuel + 1
  154.     if cost_only then
  155.         return
  156.     end
  157.  
  158.     checkFuel()
  159.     success = false
  160.     while not success do
  161.         success = turtle.down()
  162.         if not success then
  163.             while turtle.detectDown() do
  164.                 if not turtle.digDown() then
  165.                     print("Blocked attempting to move down.")
  166.                     print("Please clear and press enter to continue.")
  167.                     io.read()
  168.                 end
  169.             end
  170.         end
  171.     end
  172. end
  173.  
  174. function moveY(targety)
  175.     if targety == positiony then
  176.         return
  177.     end
  178.  
  179.     if (facing ~= 0 and facing ~= 2) then -- check axis
  180.         turnRightTrack()
  181.     end
  182.  
  183.     while targety > positiony do
  184.         if facing == 0 then
  185.             safeForward()
  186.         else
  187.             safeBack()
  188.         end
  189.         positiony = positiony + 1
  190.     end
  191.  
  192.     while targety < positiony do
  193.         if facing == 2 then
  194.             safeForward()
  195.         else
  196.             safeBack()
  197.         end
  198.         positiony = positiony - 1
  199.     end
  200. end
  201.  
  202. function moveX(targetx)
  203.     if targetx == positionx then
  204.         return
  205.     end
  206.  
  207.     if (facing ~= 1 and facing ~= 3) then -- check axis
  208.         turnRightTrack()
  209.     end
  210.  
  211.     while targetx > positionx do
  212.         if facing == 1 then
  213.             safeForward()
  214.         else
  215.             safeBack()
  216.         end
  217.         positionx = positionx + 1
  218.     end
  219.  
  220.     while targetx < positionx do
  221.         if facing == 3 then
  222.             safeForward()
  223.         else
  224.             safeBack()
  225.         end
  226.         positionx = positionx - 1
  227.     end
  228. end
  229.  
  230. function navigateTo(targetx, targety)
  231.     if facing == 0 or facing == 2 then -- Y axis
  232.         moveY(targety)
  233.         moveX(targetx)
  234.     else
  235.         moveX(targetx)
  236.         moveY(targety)
  237.     end
  238. end
  239. function line(length)
  240.     if length <= 0 then
  241.         error("Error, length can not be 0")
  242.     end
  243.     local i
  244.     for i=1, length do
  245.         placeBlock()
  246.         if i ~= length then
  247.             safeForward()
  248.         end
  249.     end
  250. end
  251. function rectangle(depth, width)
  252.     if depth <= 0 then
  253.         error("Error, depth can not be 0")
  254.     end
  255.     if width <= 0 then
  256.         error("Error, width can not be 0")
  257.     end
  258.     local lengths = {depth, width, depth, width }
  259.     local j
  260.     for j=1,4 do
  261.         line(lengths[j])
  262.         turnRightTrack()
  263.     end
  264. end
  265. function square(width)
  266.     rectangle(width, width)
  267. end
  268. function wall(length, height)
  269.     turnRightTrack()
  270.     local i
  271.     local j
  272.     for i = 1, length do
  273.         for j = 1, height do
  274.             placeBlock()
  275.             if j < height then
  276.                 safeUp()
  277.             end
  278.         end
  279.         safeForward()
  280.         for j = 1, height-1 do
  281.             safeDown()
  282.         end
  283.     end
  284.     turnLeftTrack()
  285. end
  286. function platform(x, y)
  287.     local forward = true
  288.     for cy = 0, y-1 do
  289.         for cx = 0, x-1 do
  290.             if forward then
  291.                 navigateTo(cx, cy)
  292.             else
  293.                 navigateTo(x - cx - 1, cy)
  294.             end
  295.             placeBlock()
  296.         end
  297.         if forward then
  298.             forward = false
  299.         else
  300.             forward = true
  301.         end
  302.     end
  303. end
  304. function stair(width, height)
  305.     turnRightTrack()
  306.     local cx=1
  307.     local cy=0
  308.     local goforward=0
  309.     while cy < height do
  310.         while cx < width do
  311.             placeBlock()
  312.             safeForward()
  313.             cx = cx + 1
  314.         end
  315.         placeBlock()
  316.         cx = 1
  317.         cy = cy + 1
  318.         if cy < height then
  319.             if goforward == 1 then
  320.                 turnRightTrack()
  321.                 safeUp()
  322.                 safeForward()
  323.                 turnRightTrack()
  324.                 goforward = 0
  325.             else
  326.                 turnLeftTrack()
  327.                 safeUp()
  328.                 safeForward()
  329.                 turnLeftTrack()
  330.                 goforward = 1
  331.             end
  332.         end
  333.     end
  334. end
  335. function circle(radius)
  336.     radius = tonumber(radius)
  337.  
  338.     -- Main dome and sphere building routine
  339.  
  340.     width = radius * 2 + 1
  341.     sqrt3 = 3 ^ 0.5
  342.     boundary_radius = radius + 1.0
  343.     boundary2 = boundary_radius ^ 2
  344.  
  345.     zstart = radius
  346.  
  347.     -- This loop is for each vertical layer through the sphere or dome.
  348.     for z = zstart,zstart do
  349.         --writeOut("Layer " .. z)
  350.         cz2 = (radius - z) ^ 2
  351.  
  352.         limit_offset_y = (boundary2 - cz2) ^ 0.5
  353.         max_offset_y = math.ceil(limit_offset_y)
  354.  
  355.         -- We do first the +x side, then the -x side to make movement efficient
  356.         for side = 0,1 do
  357.             -- On the right we go from small y to large y, on the left reversed
  358.             -- This makes us travel clockwise around each layer
  359.             if (side == 0) then
  360.                 ystart = radius - max_offset_y
  361.                 yend = radius + max_offset_y
  362.                 ystep = 1
  363.             else
  364.                 ystart = radius + max_offset_y
  365.                 yend = radius - max_offset_y
  366.                 ystep = -1
  367.             end
  368.  
  369.             for y = ystart,yend,ystep do
  370.                 cy2 = (radius - y) ^ 2
  371.  
  372.                 remainder2 = (boundary2 - cz2 - cy2)
  373.  
  374.  
  375.                 if remainder2 >= 0 then
  376.                     -- This is the maximum difference in x from the centre we can be without definitely being outside the radius
  377.                     max_offset_x = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
  378.  
  379.                     -- Only do either the +x or -x side
  380.                     if (side == 0) then
  381.                         -- +x side
  382.                         xstart = radius
  383.                         xend = radius + max_offset_x
  384.                     else
  385.                         -- -x side
  386.                         xstart = radius - max_offset_x
  387.                         xend = radius - 1
  388.                     end
  389.  
  390.                     -- Reverse direction we traverse xs when in -y side
  391.                     if y > radius then
  392.                         temp = xstart
  393.                         xstart = xend
  394.                         xend = temp
  395.                         xstep = -1
  396.                     else
  397.                         xstep = 1
  398.                     end
  399.  
  400.                     for x = xstart,xend,xstep do
  401.                         cx2 = (radius - x) ^ 2
  402.                         distance_to_centre = (cx2 + cy2 + cz2) ^ 0.5
  403.                         -- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
  404.                         if distance_to_centre < boundary_radius and distance_to_centre + sqrt3 >= boundary_radius then
  405.                             offsets = {{0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}
  406.                             for i=1,6 do
  407.                                 offset = offsets[i]
  408.                                 dx = offset[1]
  409.                                 dy = offset[2]
  410.                                 dz = offset[3]
  411.                                 if ((radius - (x + dx)) ^ 2 + (radius - (y + dy)) ^ 2 + (radius - (z + dz)) ^ 2) ^ 0.5 >= boundary_radius then
  412.                                     -- This is a point to use
  413.                                     navigateTo(x, y)
  414.                                     placeBlock()
  415.                                     break
  416.                                 end
  417.                             end
  418.                         end
  419.                     end
  420.                 end
  421.             end
  422.         end
  423.     end
  424.  
  425.     -- Return to where we started in x,y place and turn to face original direction
  426.     -- Don't change vertical place though - should be solid under us!
  427.     navigateTo(0, 0)
  428.     while (facing > 0) do
  429.         turnLeftTrack()
  430.     end
  431. end
  432. function dome(type, radius)
  433.     type = type
  434.     radius = tonumber(radius)
  435.  
  436.     -- Main dome and sphere building routine
  437.  
  438.     width = radius * 2 + 1
  439.     sqrt3 = 3 ^ 0.5
  440.     boundary_radius = radius + 1.0
  441.     boundary2 = boundary_radius ^ 2
  442.  
  443.     if type == "dome" then
  444.         zstart = radius
  445.     elseif type == "sphere" then
  446.         zstart = 0
  447.     else
  448.         print("Usage: sdbuild <shape> <radius> [-c]")
  449.         os.exit(1)
  450.     end
  451.     zend = width - 1
  452.  
  453.     -- This loop is for each vertical layer through the sphere or dome.
  454.     for z = zstart,zend do
  455.         if not cost_only and z ~= zstart then
  456.             safeUp()
  457.         end
  458.         --writeOut("Layer " .. z)
  459.         cz2 = (radius - z) ^ 2
  460.  
  461.         limit_offset_y = (boundary2 - cz2) ^ 0.5
  462.         max_offset_y = math.ceil(limit_offset_y)
  463.  
  464.         -- We do first the +x side, then the -x side to make movement efficient
  465.         for side = 0,1 do
  466.             -- On the right we go from small y to large y, on the left reversed
  467.             -- This makes us travel clockwise around each layer
  468.             if (side == 0) then
  469.                 ystart = radius - max_offset_y
  470.                 yend = radius + max_offset_y
  471.                 ystep = 1
  472.             else
  473.                 ystart = radius + max_offset_y
  474.                 yend = radius - max_offset_y
  475.                 ystep = -1
  476.             end
  477.  
  478.             for y = ystart,yend,ystep do
  479.                 cy2 = (radius - y) ^ 2
  480.  
  481.                 remainder2 = (boundary2 - cz2 - cy2)
  482.  
  483.  
  484.                 if remainder2 >= 0 then
  485.                     -- This is the maximum difference in x from the centre we can be without definitely being outside the radius
  486.                     max_offset_x = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
  487.  
  488.                     -- Only do either the +x or -x side
  489.                     if (side == 0) then
  490.                         -- +x side
  491.                         xstart = radius
  492.                         xend = radius + max_offset_x
  493.                     else
  494.                         -- -x side
  495.                         xstart = radius - max_offset_x
  496.                         xend = radius - 1
  497.                     end
  498.  
  499.                     -- Reverse direction we traverse xs when in -y side
  500.                     if y > radius then
  501.                         temp = xstart
  502.                         xstart = xend
  503.                         xend = temp
  504.                         xstep = -1
  505.                     else
  506.                         xstep = 1
  507.                     end
  508.  
  509.                     for x = xstart,xend,xstep do
  510.                         cx2 = (radius - x) ^ 2
  511.                         distance_to_centre = (cx2 + cy2 + cz2) ^ 0.5
  512.                         -- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
  513.                         if distance_to_centre < boundary_radius and distance_to_centre + sqrt3 >= boundary_radius then
  514.                             offsets = {{0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}
  515.                             for i=1,6 do
  516.                                 offset = offsets[i]
  517.                                 dx = offset[1]
  518.                                 dy = offset[2]
  519.                                 dz = offset[3]
  520.                                 if ((radius - (x + dx)) ^ 2 + (radius - (y + dy)) ^ 2 + (radius - (z + dz)) ^ 2) ^ 0.5 >= boundary_radius then
  521.                                     -- This is a point to use
  522.                                     navigateTo(x, y)
  523.                                     placeBlock()
  524.                                     break
  525.                                 end
  526.                             end
  527.                         end
  528.                     end
  529.                 end
  530.             end
  531.         end
  532.     end
  533.  
  534.     -- Return to where we started in x,y place and turn to face original direction
  535.     -- Don't change vertical place though - should be solid under us!
  536.     navigateTo(0, 0)
  537.     while (facing > 0) do
  538.         turnLeftTrack()
  539.     end
  540.  
  541. end
  542. writeOut("Shape Maker 1.1. Created by Michiel using a bit of Vliekkie's code")
  543. writeOut("Fixed and made readable by Aeolun ;)")
  544. writeOut("");
  545. writeOut("What should be built?")
  546. writeOut("+---------+-----------+-------+-------+")
  547. writeOut("| line    | rectangle | wall  | room  |")
  548. writeOut("| square  | platform  | stair | dome  |")
  549. writeOut("| pyramid | cylinder  | circle|       |")
  550. writeOut("+---------+-----------+-------+-------+")
  551. writeOut("")
  552.  
  553. local choice = io.read()
  554. writeOut("Building a "..choice)
  555. writeOut("Want to just calculate the cost? [y/n]")
  556. local yes = io.read()
  557. if yes == 'y' then
  558.     cost_only = true
  559. end
  560.  
  561. if not cost_only then
  562.     turtle.select(1)
  563.     activeslot = 1
  564.     if turtle.getItemCount(activeslot) == 0 then
  565.         writeOut("Please put building blocks in the first slot (and more if you need them)")
  566.         while turtle.getItemCount(activeslot) == 0 do
  567.             os.sleep(2)
  568.         end
  569.     end
  570. end
  571. if choice == "rectangle" then -- fixed
  572.     writeOut("How deep do you want it to be?")
  573.     h = io.read()
  574.     h = tonumber(h)
  575.     writeOut("How wide do you want it to be?")
  576.     v = io.read()
  577.     v = tonumber(v)
  578.     rectangle(h, v)
  579. end
  580. if choice == "square" then --fixed
  581.     writeOut("How long does it need to be?")
  582.     local s = io.read()
  583.     s = tonumber(s)
  584.     square(s)
  585. end
  586. if choice == "line" then --fixed
  587.     writeOut("How long does the line need to be?")
  588.     local ll = io.read()
  589.     ll = tonumber(ll)
  590.     line(ll)
  591. end
  592. if choice == "wall" then --fixed
  593.     writeOut("How long does it need to be?")
  594.     local wl = io.read()
  595.     wl = tonumber(wl)
  596.     writeOut("How high does it need to be?")
  597.     local wh = io.read()
  598.     wh = tonumber(wh)
  599.     if  wh <= 0 then
  600.         error("Error, the height can not be zero")
  601.     end
  602.     if wl <= 0 then
  603.         error("Error, the length can not be 0")
  604.     end
  605.     wall(wl, wh)
  606. end
  607. if choice == "platform" then
  608.     writeOut("How long do you want it to be?")
  609.     x = io.read()
  610.     x = tonumber(x)
  611.     writeOut("How wide do you want it to be?")
  612.     y = io.read()
  613.     y = tonumber(y)
  614.     platform(x, y)
  615.     writeOut("Done")
  616. end
  617. if choice == "stair" then --fixed
  618.     writeOut("How wide do you want it to be?")
  619.     x = io.read()
  620.     x = tonumber(x)
  621.     writeOut("How high do you want it to be?")
  622.     y = io.read()
  623.     y = tonumber(y)
  624.     stair(x, y)
  625.     writeOut("Done")
  626. end
  627. if choice == "room" then
  628.     writeOut("How deep does it need to be?")
  629.     local cl = io.read()
  630.     cl = tonumber(cl)
  631.     writeOut("How wide does it need to be?")
  632.     local ch = io.read()
  633.     ch = tonumber(ch)
  634.     writeOut("How high does it need to be?")
  635.     local hi = io.read()
  636.     hi = tonumber(hi)
  637.     if hi < 3 then
  638.         hi = 3
  639.     end
  640.     if cl < 3 then
  641.         cl = 3
  642.     end
  643.     if ch < 3 then
  644.         ch = 3
  645.     end
  646.  
  647.     platform(cl, ch)
  648.     while (facing > 0) do
  649.         turnLeftTrack()
  650.     end
  651.     turnAroundTrack()
  652.     for i = 1, hi-2 do
  653.         safeUp()
  654.         rectangle(cl, ch)
  655.     end
  656.     safeUp()
  657.     platform(cl, ch)
  658. end
  659. if choice == "dome" then
  660.     writeOut("What radius do you need it to be?")
  661.     local rad = io.read()
  662.     rad = tonumber(rad)
  663.     dome("dome", rad)
  664. end
  665. if choice == "sphere" then
  666.     writeOut("What radius do you need it to be?")
  667.     local rad = io.read()
  668.     rad = tonumber(rad)
  669.     dome("sphere", rad)
  670. end
  671. if choice == "circle" then
  672.     writeOut("What radius do you need it to be?")
  673.     local rad = io.read()
  674.     rad = tonumber(rad)
  675.     circle(rad)
  676. end
  677. if choice == "cylinder" then
  678.     writeOut("What radius do you need it to be?")
  679.     local rad = io.read()
  680.     rad = tonumber(rad)
  681.     writeOut("What height do you need it to be?")
  682.     local height = io.read()
  683.     height = tonumber(height)
  684.  
  685.     for i = 1, height do
  686.         circle(rad)
  687.         safeUp()
  688.     end
  689.     for i = 1, height do
  690.         safeDown()
  691.     end
  692. end
  693. if choice == "pyramid" then
  694.     writeOut("What width/depth do you need it to be?")
  695.     local width = io.read()
  696.     width = tonumber(width)
  697.     writeOut("Do you want it to be hollow [y/n]?")
  698.     local hollow = io.read()
  699.     if hollow == 'y' then
  700.         hollow = true
  701.     else
  702.         hollow = false
  703.     end
  704.  
  705.  
  706.     height = math.ceil(width / 2)
  707.     for i = 1, height do
  708.         if hollow then
  709.             rectangle(width, width)
  710.         else
  711.             platform(width, width)
  712.             navigateTo(0,0)
  713.             while facing ~= 0 do
  714.                 turnRightTrack()
  715.             end
  716.         end
  717.         if i ~= height then
  718.             safeUp()
  719.             safeForward()
  720.             turnRightTrack()
  721.             safeForward()
  722.             turnLeftTrack()
  723.             width = width - 2
  724.         end
  725.     end
  726. end
  727.  
  728. print("Blocks used: " .. blocks)
  729. print("Fuel used: " .. fuel)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement