Guest User

Minecraft Turtle Shapebuilder

a guest
Jul 1st, 2014
344
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 42.13 KB | None | 0 0
  1. -- Variable Setup
  2. -- Command Line input Table
  3. local argTable = {...}
  4.  
  5. -- Flag Variables: These are conditions for different features (all flags are named foo_bar, all other variables are named fooBar)
  6. local cmd_line = false
  7. local cmd_line_resume = false
  8. local cmd_line_cost_only = false
  9. local chain_next_shape = false -- This tells goHome() where to end, if true it goes to (0, 0, positionZ) if false it goes to (-1, -1, 0)
  10. local special_chain = false -- For certain shapes that finish where the next chained shape should start, goHome() will  only turn to face 0 if true
  11. local cost_only = false
  12. local sim_mode = false
  13.  
  14. -- Record Keeping Variables: These are for recoding the blocks and fuel used
  15. local blocks = 0
  16. local fuel = 0
  17.  
  18. -- Position Tracking Variables: These are for keeping track of the turtle's position
  19. local positionX = 0
  20. local positionY = 0
  21. local positionZ = 0
  22. local facing = 0
  23. local gpsPositionX = 0
  24. local gpsPositionY = 0
  25. local gpsPositionZ = 0
  26. local gpsFacing = 0
  27.  
  28. -- General Variables: Other variables that don't fit in the other categories
  29. local resupply = false
  30. local enderchestRefilling = false
  31. local can_use_gps = false
  32. local returntohome = false -- whether the turtle shall return to start after build
  33. local choice = ""
  34.  
  35. -- Progress Table: These variables are the tables that the turtle's progress is tracked in
  36. local tempProgTable = {}
  37. local progTable = {} --This is the LOCAL table!  used for local stuff only, and is ONLY EVER WRITTEN when sim_mode is FALSE
  38. local progFileName = "ShapesProgressFile"
  39.  
  40. -- Utility functions
  41.  
  42. function writeOut(...) -- ... lets writeOut() pass any arguments to print(). so writeOut(1,2,3) is the same as print(1,2,3). previously writeOut(1,2,3) would have been the same as print(1)
  43.     for i, v in ipairs(arg) do
  44.         print(v)
  45.     end
  46. end
  47.  
  48. function getInput(inputtype, message, option1, option2)
  49.     local input = ""
  50.     if inputtype == "string" then
  51.         writeOut(message.. "(" ..option1 .. " or "..option2..")" )
  52.         while true do
  53.             input = io.read()
  54.             input = string.lower(input)
  55.             if input ~= option1 and input ~= option2 then
  56.                 writeOut("You didn't enter a valid option. Please try again.")
  57.             else
  58.                 return input
  59.             end
  60.         end
  61.     end
  62.     if inputtype == "int" then
  63.         writeOut(message)
  64.         while true do
  65.             input = io.read()
  66.             if tonumber(input) ~= nil then
  67.                 return tonumber(input)
  68.             else
  69.                 writeOut("Need a number. Please try again")
  70.             end
  71.         end
  72.     end
  73. end
  74.  
  75. function wrapmodules() -- checks for and wraps turtle modules
  76.     local test = 0
  77.     if peripheral.getType("left" )== "resupply" then
  78.         resupplymodule=peripheral.wrap("left")
  79.         resupply = true
  80.     elseif peripheral.getType("right") == "resupply" then
  81.         resupplymodule=peripheral.wrap("right")
  82.         resupply = true
  83.     end
  84.     if peripheral.getType("left") == "modem" then
  85.         modem=peripheral.wrap("left")
  86.         test, _, _ = gps.locate(1)
  87.         if test ~= nil then
  88.             can_use_gps = true
  89.         end
  90.     elseif peripheral.getType("right") == "modem" then
  91.         modem=peripheral.wrap("right")
  92.         test, _, _ = gps.locate(1)
  93.         if test ~= nil then
  94.             can_use_gps = true
  95.         end
  96.     end
  97.     if resupply then
  98.         return "resupply"
  99.     end
  100. end
  101.  
  102. function linkToRSStation() -- Links to resupply station
  103.     if resupplymodule.link() then
  104.         return true
  105.     else
  106.         writeOut("Please put Resupply Station to the left of the turtle and press Enter to continue")
  107.         io.read()
  108.         linkToRSStation()
  109.     end
  110. end
  111.  
  112. function compareResources()
  113.     if (turtle.compareTo(1) == false) then
  114.         turtle.drop()
  115.     end
  116. end
  117.  
  118. function checkResources()
  119.     if resupply then
  120.         if turtle.getItemCount(activeslot) <= 1 then
  121.             while not(resupplymodule.resupply(1)) do
  122.                 os.sleep(0.5)
  123.             end
  124.         end
  125.     elseif enderchestRefilling then
  126.         compareResources()
  127.         while (turtle.getItemCount(activeslot) <= 1) do
  128.             if (activeslot == 15) and (turtle.getItemCount(activeslot)<=1) then
  129.                 turtle.select(16)
  130.                 turtle.digUp()
  131.                 for i = 1, 15 do
  132.                     turtle.select(i)
  133.                     turtle.drop()
  134.                 end
  135.                 turtle.select(16)
  136.                 turtle.placeUp()
  137.                 turtle.select(1)               
  138.                 for i = 1, 15 do
  139.                     turtle.suckUp()
  140.                 end
  141.                 turtle.select(16)
  142.                 turtle.digUp()
  143.                 activeslot = 1
  144.                 turtle.select(activeslot)
  145.             else
  146.                 activeslot = activeslot+1
  147.                 -- writeOut("Turtle slot empty, trying slot "..activeslot)
  148.                 turtle.select(activeslot)
  149.             end
  150.             compareResources()
  151.             os.sleep(0.2)
  152.         end
  153.     else
  154.         compareResources()
  155.         while (turtle.getItemCount(activeslot) <= 1) do
  156.             if (activeslot == 16) and (turtle.getItemCount(activeslot)<=1) then
  157.                 writeOut("Turtle is empty, please put building block in slots and press enter to continue")
  158.                 io.read()
  159.                 activeslot = 1
  160.                 turtle.select(activeslot)
  161.             else
  162.                 activeslot = activeslot+1
  163.                 -- writeOut("Turtle slot almost empty, trying slot "..activeslot)
  164.                 turtle.select(activeslot)
  165.             end
  166.             compareResources()
  167.             os.sleep(0.2)
  168.         end
  169.     end
  170. end
  171.  
  172. function checkFuel()
  173.     if (not(tonumber(turtle.getFuelLevel()) == nil)) then
  174.         while turtle.getFuelLevel() < 50 do
  175.             writeOut("Turtle almost out of fuel, pausing. Please drop fuel in inventory. And press enter.")
  176.             io.read()
  177.             turtle.refuel()
  178.         end
  179.     end
  180. end
  181.  
  182. function placeBlock()
  183.     blocks = blocks + 1
  184.     simulationCheck()
  185.     if cost_only then
  186.         return
  187.     end
  188.     if turtle.detectDown() and not turtle.compareDown() then
  189.         turtle.digDown()
  190.     end
  191.     checkResources()
  192.     turtle.placeDown()
  193.     progressUpdate()
  194. end
  195.  
  196. function round(toBeRounded, decimalPlace) -- Needed for hexagon and octagon
  197.     local multiplier = 10^(decimalPlace or 0)
  198.     return math.floor(toBeRounded * multiplier + 0.5) / multiplier
  199. end
  200.  
  201. -- Navigation functions
  202. -- Allow the turtle to move while tracking its position
  203. -- This allows us to just give a destination point and have it go there
  204.  
  205. function turnRightTrack()
  206.     simulationCheck()
  207.     facing = facing + 1
  208.     if facing >= 4 then
  209.         facing = 0
  210.     end
  211.     progressUpdate()
  212.     if cost_only then
  213.         return
  214.     end
  215.     turtle.turnRight()
  216. end
  217.  
  218. function turnLeftTrack()
  219.     simulationCheck()
  220.     facing = facing - 1
  221.     if facing < 0 then
  222.         facing = 3
  223.     end
  224.     progressUpdate()
  225.     if cost_only then
  226.         return
  227.     end
  228.     turtle.turnLeft()
  229. end
  230.  
  231. function turnAroundTrack()
  232.     turnLeftTrack()
  233.     turnLeftTrack()
  234. end
  235.  
  236. function turnToFace(direction)
  237.     if direction >= 4 or direction < 0 then
  238.         return false
  239.     end
  240.     while facing ~= direction do
  241.         turnLeftTrack()
  242.     end
  243.     return true
  244. end
  245.  
  246. function safeForward()
  247.     simulationCheck()
  248.     if facing == 0 then
  249.         positionY = positionY + 1
  250.     elseif facing == 1 then
  251.         positionX = positionX + 1
  252.     elseif facing == 2 then
  253.         positionY = positionY - 1
  254.     elseif facing == 3 then
  255.         positionX = positionX - 1
  256.     end
  257.     fuel = fuel + 1
  258.     progressUpdate()
  259.     if cost_only then
  260.         return
  261.     end
  262.     checkFuel()
  263.     local success = false
  264.     local tries = 0
  265.     while not success do
  266.         success = turtle.forward()
  267.         if not success then
  268.             while (not success) and tries < 6 do
  269.                 tries = tries + 1
  270.                 turtle.dig()
  271.                 success = turtle.forward()
  272.                 sleep(0.3)
  273.             end
  274.             if not success then
  275.                 writeOut("Blocked attempting to move forward.")
  276.                 writeOut("Please clear and press enter to continue.")
  277.                 io.read()
  278.             end
  279.         end
  280.     end
  281. end
  282.  
  283. function safeBack()
  284.     simulationCheck()
  285.     if facing == 0 then
  286.         positionY = positionY - 1
  287.     elseif facing == 1 then
  288.         positionX = positionX - 1
  289.     elseif facing == 2 then
  290.         positionY = positionY + 1
  291.     elseif facing == 3 then
  292.         positionX = positionX + 1
  293.     end
  294.     fuel = fuel + 1
  295.     progressUpdate()
  296.     if cost_only then
  297.         return
  298.     end
  299.     checkFuel()
  300.     local success = false
  301.     local tries = 0
  302.     while not success do
  303.         success = turtle.back()
  304.         if not success then
  305.             turnAroundTrack()
  306.             while turtle.detect() and tries < 6 do
  307.                 tries = tries + 1
  308.                 if turtle.dig() then
  309.                     break
  310.                 end
  311.                 sleep(0.3)
  312.             end
  313.             turnAroundTrack()
  314.             success = turtle.back()
  315.             if not success then
  316.                 writeOut("Blocked attempting to move back.")
  317.                 writeOut("Please clear and press enter to continue.")
  318.                 io.read()
  319.             end
  320.         end
  321.     end
  322. end
  323.  
  324. function safeUp()
  325.     simulationCheck()
  326.     positionZ = positionZ + 1
  327.     fuel = fuel + 1
  328.     progressUpdate()
  329.     if cost_only then
  330.         return
  331.     end
  332.     checkFuel()
  333.     local success = false
  334.     while not success do
  335.         success = turtle.up()
  336.         if not success then
  337.             while turtle.detectUp() do
  338.                 if not turtle.digUp() then
  339.                     writeOut("Blocked attempting to move up.")
  340.                     writeOut("Please clear and press enter to continue.")
  341.                     io.read()
  342.                 end
  343.             end
  344.         end
  345.     end
  346. end
  347.  
  348. function safeDown()
  349.     simulationCheck()
  350.     positionZ = positionZ - 1
  351.     fuel = fuel + 1
  352.     progressUpdate()
  353.     if cost_only then
  354.         return
  355.     end
  356.     checkFuel()
  357.     local success = false
  358.     while not success do
  359.         success = turtle.down()
  360.         if not success then
  361.             while turtle.detectDown() do
  362.                 if not turtle.digDown() then
  363.                     writeOut("Blocked attempting to move down.")
  364.                     writeOut("Please clear and press enter to continue.")
  365.                     io.read()
  366.                 end
  367.             end
  368.         end
  369.     end
  370. end
  371.  
  372. function moveY(targetY)
  373.     if targetY == positionY then
  374.         return
  375.     end
  376.     if (facing ~= 0 and facing ~= 2) then -- Check axis
  377.         turnRightTrack()
  378.     end
  379.     while targetY > positionY do
  380.         if facing == 0 then
  381.             safeForward()
  382.         else
  383.             safeBack()
  384.         end
  385.     end
  386.     while targetY < positionY do
  387.         if facing == 2 then
  388.             safeForward()
  389.         else
  390.             safeBack()
  391.         end
  392.     end
  393. end
  394.  
  395. function moveX(targetX)
  396.     if targetX == positionX then
  397.         return
  398.     end
  399.     if (facing ~= 1 and facing ~= 3) then -- Check axis
  400.         turnRightTrack()
  401.     end
  402.     while targetX > positionX do
  403.         if facing == 1 then
  404.             safeForward()
  405.         else
  406.             safeBack()
  407.         end
  408.     end
  409.     while targetX < positionX do
  410.         if facing == 3 then
  411.             safeForward()
  412.         else
  413.             safeBack()
  414.         end
  415.     end
  416. end
  417.  
  418. function moveZ(targetZ)
  419.     if targetZ == positionZ then
  420.         return
  421.     end
  422.     while targetZ < positionZ do
  423.         safeDown()
  424.     end
  425.     while targetZ > positionZ do
  426.         safeUp()
  427.     end
  428. end
  429.  
  430. -- I *HIGHLY* suggest formatting all shape subroutines to use the format that dome() uses;  specifically, navigateTo(x,y,[z]) then placeBlock().  This should ensure proper "data recording" and also makes readability better
  431. function navigateTo(targetX, targetY, targetZ, move_z_first)
  432.     targetZ = targetZ or positionZ -- If targetZ isn't used in the function call, it defaults to its current z position, this should make it compatible with all previous implementations of navigateTo()
  433.     move_z_first = move_z_first or false -- Defaults to moving z last, if true is passed as 4th argument, it moves vertically first
  434.    
  435.     if move_z_first then
  436.         moveZ(targetZ)
  437.     end
  438.    
  439.     if facing == 0 or facing == 2 then -- Y axis
  440.         moveY(targetY)
  441.         moveX(targetX)
  442.     else
  443.         moveX(targetX)
  444.         moveY(targetY)
  445.     end
  446.    
  447.     if not move_z_first then
  448.         moveZ(targetZ)
  449.     end
  450. end
  451.  
  452. function goHome()
  453.     if chain_next_shape then
  454.         if not special_chain then
  455.             navigateTo(0, 0) -- So another program can chain multiple shapes together to create bigger structures
  456.         end
  457.     else
  458.         navigateTo(-1, -1, 0) -- So the user can collect the turtle when it is done -- also not 0,0,0 because some shapes use the 0,0 column
  459.     end
  460.     turnToFace(0)
  461. end
  462.  
  463. -- Shape Building functions
  464.  
  465. function line(length)
  466.     if length <= 0 then
  467.         error("Error, length can not be 0")
  468.     end
  469.     local i
  470.     for i = 1, length do
  471.         placeBlock()
  472.         if i ~= length then
  473.             safeForward()
  474.         end
  475.     end
  476. end
  477.  
  478. function rectangle(depth, width)
  479.     if depth <= 0 then
  480.         error("Error, depth can not be 0")
  481.     end
  482.     if width <= 0 then
  483.         error("Error, width can not be 0")
  484.     end
  485.     local lengths = {depth, width, depth, width }
  486.     local j
  487.     for j=1,4 do
  488.         line(lengths[j])
  489.         turnRightTrack()
  490.     end
  491. end
  492.  
  493. function square(width)
  494.     rectangle(width, width)
  495. end
  496.  
  497. function wall(length, height)
  498.     local i
  499.     local j
  500.     for i = 1, length do
  501.         for j = 1, height do
  502.             placeBlock()
  503.             if j < height then
  504.                 safeUp()
  505.             end
  506.         end
  507.         safeForward()
  508.         for j = 1, height - 1 do
  509.             safeDown()
  510.         end
  511.     end
  512.     turnLeftTrack()
  513. end
  514.  
  515. function platform(x, y)
  516.     local forward = true
  517.     for counterY = 0, y - 1 do
  518.         for counterX = 0, x - 1 do
  519.             if forward then
  520.                 navigateTo(counterX, counterY)
  521.             else
  522.                 navigateTo(x - counterX - 1, counterY)
  523.             end
  524.             placeBlock()
  525.         end
  526.         if forward then
  527.             forward = false
  528.         else
  529.             forward = true
  530.         end
  531.     end
  532. end
  533.  
  534. function cuboid(depth, width, height, hollow)
  535.     platform(depth, width)
  536.     while (facing > 0) do
  537.         turnLeftTrack()
  538.     end
  539.     turnAroundTrack()
  540.     if ((width % 2) == 0) then -- This is for reorienting the turtle to build the walls correct in relation to the floor and ceiling
  541.         turnLeftTrack()
  542.     end
  543.     if not(hollow == "n") then
  544.         for i = 1, height - 2 do
  545.             safeUp()
  546.             if ((width % 2) == 0) then -- This as well
  547.             rectangle(depth, width)
  548.             else
  549.             rectangle(width, depth)
  550.             end
  551.         end
  552.     else
  553.         for i = 1, height - 2 do
  554.             safeUp()
  555.             platform(depth,width)
  556.         end
  557.     end
  558.     safeUp()
  559.     platform(depth, width)
  560. end
  561.  
  562. function pyramid(length, hollow)
  563.     height = math.ceil(length / 2)
  564.     for i = 1, height do
  565.         if hollow=="y" then
  566.             rectangle(length, length)
  567.         else
  568.             platform(length, length)
  569.             navigateTo(0,0)
  570.             while facing ~= 0 do
  571.                 turnRightTrack()
  572.             end
  573.         end
  574.         if i ~= height then
  575.             safeUp()
  576.             safeForward()
  577.             turnRightTrack()
  578.             safeForward()
  579.             turnLeftTrack()
  580.             length = length - 2
  581.         end
  582.     end
  583. end
  584.  
  585. function stair(width, height)
  586.     turnRightTrack()
  587.     local counterX = 1
  588.     local counterY = 0
  589.     local goForward = 0
  590.     while counterY < height do
  591.         while counterX < width do
  592.             placeBlock()
  593.             safeForward()
  594.             counterX = counterX + 1
  595.         end
  596.         placeBlock()
  597.         counterX = 1
  598.         counterY = counterY + 1
  599.         if counterY < height then
  600.             if goForward == 1 then
  601.                 turnRightTrack()
  602.                 safeUp()
  603.                 safeForward()
  604.                 turnRightTrack()
  605.                 goForward = 0
  606.             else
  607.                 turnLeftTrack()
  608.                 safeUp()
  609.                 safeForward()
  610.                 turnLeftTrack()
  611.                 goForward = 1
  612.             end
  613.         end
  614.     end
  615. end
  616.  
  617. function circle(diameter)
  618.     odd = not (math.fmod(diameter, 2) == 0)
  619.     radius = diameter / 2;
  620.     if odd then
  621.         width = (2 * math.ceil(radius)) + 1;
  622.         offset = math.floor(width/2);
  623.     else
  624.         width = (2 * math.ceil(radius)) + 2;
  625.         offset = math.floor(width/2) - 0.5;    
  626.     end
  627.     --diameter --radius * 2 + 1
  628.     sqrt3 = 3 ^ 0.5
  629.     boundaryRadius = radius + 1.0
  630.     boundary2 = boundaryRadius ^ 2
  631.     radius2 = radius ^ 2
  632.     z = math.floor(radius)
  633.     cz2 = (radius - z) ^ 2
  634.     limitOffsetY = (boundary2 - cz2) ^ 0.5
  635.     maxOffsetY = math.ceil(limitOffsetY)
  636.     -- We do first the +x side, then the -x side to make movement efficient
  637.     for side = 0,1 do
  638.             -- On the right we go from small y to large y, on the left reversed
  639.             -- This makes us travel clockwise (from below) around each layer
  640.             if (side == 0) then
  641.                 yStart = math.floor(radius) - maxOffsetY
  642.                 yEnd = math.floor(radius) + maxOffsetY
  643.                 yStep = 1
  644.             else
  645.                 yStart = math.floor(radius) + maxOffsetY
  646.                 yEnd = math.floor(radius) - maxOffsetY
  647.                 yStep = -1
  648.             end
  649.             for y = yStart,yEnd,yStep do
  650.                 cy2 = (radius - y) ^ 2
  651.                 remainder2 = (boundary2 - cz2 - cy2)
  652.                 if remainder2 >= 0 then
  653.                     -- This is the maximum difference in x from the centre we can be without definitely being outside the radius
  654.                     maxOffsetX = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
  655.                     -- Only do either the +x or -x side
  656.                     if (side == 0) then
  657.                         -- +x side
  658.                         xStart = math.floor(radius)
  659.                         xEnd = math.floor(radius) + maxOffsetX
  660.                     else
  661.                         -- -x side
  662.                         xStart = math.floor(radius) - maxOffsetX
  663.                         xEnd = math.floor(radius) - 1
  664.                     end
  665.                     -- Reverse direction we traverse xs when in -y side
  666.                     if y > math.floor(radius) then
  667.                         temp = xStart
  668.                         xStart = xEnd
  669.                         xEnd = temp
  670.                         xStep = -1
  671.                     else
  672.                         xStep = 1
  673.                     end
  674.  
  675.                     for x = xStart,xEnd,xStep do
  676.                         -- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
  677.                         if isSphereBorder(offset, x, y, z, radius2) then
  678.                             navigateTo(x, y)
  679.                             placeBlock()
  680.                         end
  681.                     end
  682.                 end
  683.             end
  684.         end
  685. end
  686.  
  687. function blockInSphereIsFull(offset, x, y, z, radiusSq)
  688.     x = x - offset
  689.     y = y - offset
  690.     z = z - offset
  691.     x = x ^ 2
  692.     y = y ^ 2
  693.     z = z ^ 2
  694.     return x + y + z <= radiusSq
  695. end
  696.  
  697. function isSphereBorder(offset, x, y, z, radiusSq)
  698.     spot = blockInSphereIsFull(offset, x, y, z, radiusSq)
  699.     if spot then
  700.         spot = not blockInSphereIsFull(offset, x, y - 1, z, radiusSq) or
  701.             not blockInSphereIsFull(offset, x, y + 1, z, radiusSq) or
  702.             not blockInSphereIsFull(offset, x - 1, y, z, radiusSq) or
  703.             not blockInSphereIsFull(offset, x + 1, y, z, radiusSq) or
  704.             not blockInSphereIsFull(offset, x, y, z - 1, radiusSq) or
  705.             not blockInSphereIsFull(offset, x, y, z + 1, radiusSq)
  706.     end
  707.     return spot
  708. end
  709.  
  710. function dome(typus, diameter)
  711.     -- Main dome and sphere building routine
  712.     odd = not (math.fmod(diameter, 2) == 0)
  713.     radius = diameter / 2;
  714.     if odd then
  715.         width = (2 * math.ceil(radius)) + 1;
  716.         offset = math.floor(width/2);
  717.     else
  718.         width = (2 * math.ceil(radius)) + 2;
  719.         offset = math.floor(width/2) - 0.5;    
  720.     end
  721.     --diameter --radius * 2 + 1
  722.     sqrt3 = 3 ^ 0.5
  723.     boundaryRadius = radius + 1.0
  724.     boundary2 = boundaryRadius ^ 2
  725.     radius2 = radius ^ 2
  726.    
  727.     if typus == "dome" then
  728.         zstart = math.ceil(radius)
  729.     elseif typus == "sphere" then
  730.         zstart = 1
  731.     elseif typus == "bowl" then
  732.         zstart = 1
  733.     end
  734.     if typus == "bowl" then
  735.         zend = math.floor(radius)
  736.     else
  737.         zend = width - 1
  738.     end
  739.  
  740.     -- This loop is for each vertical layer through the sphere or dome.
  741.     for z = zstart,zend do
  742.         if not cost_only and z ~= zstart then
  743.             safeUp()
  744.         end
  745.         --writeOut("Layer " .. z)
  746.         cz2 = (radius - z) ^ 2
  747.         limitOffsetY = (boundary2 - cz2) ^ 0.5
  748.         maxOffsetY = math.ceil(limitOffsetY)
  749.         -- We do first the +x side, then the -x side to make movement efficient
  750.         for side = 0,1 do
  751.             -- On the right we go from small y to large y, on the left reversed
  752.             -- This makes us travel clockwise (from below) around each layer
  753.             if (side == 0) then
  754.                 yStart = math.floor(radius) - maxOffsetY
  755.                 yEnd = math.floor(radius) + maxOffsetY
  756.                 yStep = 1
  757.             else
  758.                 yStart = math.floor(radius) + maxOffsetY
  759.                 yEnd = math.floor(radius) - maxOffsetY
  760.                 yStep = -1
  761.             end
  762.             for y = yStart,yEnd,yStep do
  763.                 cy2 = (radius - y) ^ 2
  764.                 remainder2 = (boundary2 - cz2 - cy2)
  765.                 if remainder2 >= 0 then
  766.                     -- This is the maximum difference in x from the centre we can be without definitely being outside the radius
  767.                     maxOffsetX = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
  768.                     -- Only do either the +x or -x side
  769.                     if (side == 0) then
  770.                         -- +x side
  771.                         xStart = math.floor(radius)
  772.                         xEnd = math.floor(radius) + maxOffsetX
  773.                     else
  774.                         -- -x side
  775.                         xStart = math.floor(radius) - maxOffsetX
  776.                         xEnd = math.floor(radius) - 1
  777.                     end
  778.                     -- Reverse direction we traverse xs when in -y side
  779.                     if y > math.floor(radius) then
  780.                         temp = xStart
  781.                         xStart = xEnd
  782.                         xEnd = temp
  783.                         xStep = -1
  784.                     else
  785.                         xStep = 1
  786.                     end
  787.  
  788.                     for x = xStart,xEnd,xStep do
  789.                         -- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
  790.                         if isSphereBorder(offset, x, y, z, radius2) then
  791.                             navigateTo(x, y)
  792.                             placeBlock()
  793.                         end
  794.                     end
  795.                 end
  796.             end
  797.         end
  798.     end
  799. end
  800.  
  801. function cylinder(diameter, height)
  802.     for i = 1, height do
  803.         circle(diameter)
  804.         safeUp()
  805.     end
  806. end
  807.  
  808. function hexagon(sideLength)
  809.     local changeX = sideLength / 2
  810.     local changeY = round(math.sqrt(3) * changeX, 0)
  811.     changeX = round(changeX, 0)
  812.     local counter = 0
  813.  
  814.     navigateTo(changeX, 0)
  815.  
  816.     for currentSide = 1, 6 do
  817.         counter = 0
  818.  
  819.         if currentSide == 1 then
  820.             for placed = 1, sideLength do
  821.                 navigateTo(positionX + 1, positionY)
  822.                 placeBlock()
  823.             end
  824.         elseif currentSide == 2 then
  825.             navigateTo(positionX, positionY + 1)
  826.             while positionY <= changeY do
  827.                 if counter == 0 or counter == 2 or counter == 4 then
  828.                     navigateTo(positionX + 1, positionY)
  829.                 end
  830.                 placeBlock()
  831.                 navigateTo(positionX, positionY + 1)
  832.                 counter = counter + 1
  833.                 if counter == 5 then
  834.                     counter = 0
  835.                 end
  836.             end
  837.         elseif currentSide == 3 then
  838.             while positionY <= (2 * changeY) do
  839.                 if counter == 0 or counter == 2 or counter == 4 then
  840.                     navigateTo(positionX - 1, positionY)
  841.                 end
  842.                 placeBlock()
  843.                 navigateTo(positionX, positionY + 1)
  844.                 counter = counter + 1
  845.                 if counter == 5 then
  846.                     counter = 0
  847.                 end
  848.             end
  849.         elseif currentSide == 4 then
  850.             for placed = 1, sideLength do
  851.                 navigateTo(positionX - 1, positionY)
  852.                 placeBlock()
  853.             end
  854.         elseif currentSide == 5 then
  855.             navigateTo(positionX, positionY - 1)
  856.             while positionY >= changeY do
  857.                 if counter == 0 or counter == 2 or counter == 4 then
  858.                     navigateTo(positionX - 1, positionY)
  859.                 end
  860.                 placeBlock()
  861.                 navigateTo(positionX, positionY - 1)
  862.                 counter = counter + 1
  863.                 if counter == 5 then
  864.                     counter = 0
  865.                 end
  866.             end
  867.         elseif currentSide == 6 then
  868.             while positionY >= 0 do
  869.                 if counter == 0 or counter == 2 or counter == 4 then
  870.                     navigateTo(positionX + 1, positionY)
  871.                 end
  872.                 placeBlock()
  873.                 navigateTo(positionX, positionY - 1)
  874.                 counter = counter + 1
  875.                 if counter == 5 then
  876.                     counter = 0
  877.                 end
  878.             end
  879.         end
  880.     end
  881. end
  882.  
  883. function octagon(sideLength)
  884.     local sideLength2 = sideLength - 1
  885.     local change = round(sideLength2 / math.sqrt(2), 0)
  886.  
  887.     navigateTo(change, 0)
  888.  
  889.     for currentSide = 1, 8 do
  890.         if currentSide == 1 then
  891.             for placed = 1, sideLength2 do
  892.                 navigateTo(positionX + 1, positionY)
  893.                 placeBlock()
  894.             end
  895.         elseif currentSide == 2 then
  896.             for placed = 1, change do
  897.                 navigateTo(positionX + 1, positionY + 1)
  898.                 placeBlock()
  899.             end
  900.         elseif currentSide == 3 then
  901.             for placed = 1, sideLength2 do
  902.                 navigateTo(positionX, positionY + 1)
  903.                 placeBlock()
  904.             end
  905.         elseif currentSide == 4 then
  906.             for placed = 1, change do
  907.                 navigateTo(positionX - 1, positionY + 1)
  908.                 placeBlock()
  909.             end
  910.         elseif currentSide == 5 then
  911.             for placed = 1, sideLength2 do
  912.                 navigateTo(positionX - 1, positionY)
  913.                 placeBlock()
  914.             end
  915.         elseif currentSide == 6 then
  916.             for placed = 1, change do
  917.                 navigateTo(positionX - 1, positionY - 1)
  918.                 placeBlock()
  919.             end
  920.         elseif currentSide == 7 then
  921.         for placed = 1, sideLength2 do
  922.                 navigateTo(positionX, positionY - 1)
  923.                 placeBlock()
  924.             end
  925.         elseif currentSide == 8 then
  926.             for placed = 1, change do
  927.                 navigateTo(positionX + 1, positionY - 1)
  928.                 placeBlock()
  929.             end
  930.         end
  931.     end
  932. end
  933.  
  934. function sixprism(length, height)
  935.     for i = 1, height do
  936.         hexagon(length)
  937.         safeUp()
  938.     end
  939. end
  940.  
  941. function eightprism(length, height)
  942.     for i = 1, height do
  943.         octagon(length)
  944.         safeUp()
  945.     end
  946. end
  947.  
  948. -- Previous Progress Resuming, Simulation functions, Command Line, and File Backend
  949. -- Will check for a "progress" file.
  950. function CheckForPrevious()
  951.     if fs.exists(progFileName) then
  952.         return true
  953.     else
  954.         return false
  955.     end
  956. end
  957.  
  958. -- Creates a progress file, containing a serialized table consisting of the shape type, shape input params, and the last known x, y, and z coords of the turtle (beginning of build project)
  959. function ProgressFileCreate()
  960.     if not CheckForPrevious() then
  961.         fs.makeDir(progFileName)
  962.         return true
  963.     else
  964.         return false
  965.     end
  966. end
  967.  
  968. -- Deletes the progress file (at the end of the project, also at beginning if user chooses to delete old progress)
  969. function ProgressFileDelete()
  970.     if fs.exists(progFileName) then
  971.         fs.delete(progFileName)
  972.         return true
  973.     else
  974.         return false
  975.     end
  976. end
  977.  
  978. -- To read the shape params from the file.  Shape type, and input params (e.g. "dome" and radius)
  979. function ReadShapeParams()
  980.     -- TODO. Unneeded for now, can just use the table elements directly
  981. end
  982.  
  983. function WriteShapeParams(...) -- The ... lets it take any number of arguments and stores it to the table arg{} | This is still unused anywhere
  984.     local paramTable = arg
  985.     local paramName = "param"
  986.     local paramName2 = paramName
  987.     for i, v in ipairs(paramTable) do -- Iterates through the args passed to the function, ex. paramTable[1] i = 1 so paramName2 should be "param1", tested and works!
  988.         paramName2 = paramName .. i
  989.         tempProgTable[paramName2] = v
  990.         progTable[paramName2] = v
  991.     end
  992. end
  993.  
  994. -- function to write the progress to the file (x, y, z)
  995. function writeProgress()
  996.     local progFile
  997.     local progString = ""
  998.     if not (sim_mode or cost_only) then
  999.         progString = textutils.serialize(progTable) -- Put in here to save processing time when in cost_only
  1000.         progFile = fs.open(progFileName, "w")
  1001.         progFile.write(progString)
  1002.         progFile.close()
  1003.     end
  1004.  
  1005. end
  1006.  
  1007. -- Reads progress from file (shape, x, y, z, facing, blocks, param1, param2, param3)
  1008. function readProgress()
  1009.     local progFile = fs.open(progFileName, "r")
  1010.     local readProgTable = textutils.unserialize(progFile.readAll())
  1011.     progFile.close()
  1012.     return readProgTable
  1013. end
  1014.  
  1015. -- compares the progress read from the file to the current sim progress.  needs all four params
  1016. function compareProgress()
  1017.     local progTableIn = progTable
  1018.     local readProgTable = readProgress()
  1019.     if (progTableIn.shape == readProgTable.shape and progTableIn.x == readProgTable.x and progTableIn.y == readProgTable.y and progTableIn.blocks == readProgTable.blocks and progTableIn.facing == readProgTable.facing) then
  1020.         writeOut("All caught up!")
  1021.         return true -- We're caught up!
  1022.     else
  1023.         return false -- Not there yet...
  1024.     end
  1025. end
  1026.  
  1027. function getGPSInfo() -- TODO: finish this
  1028.     position = gps.locate()
  1029.     gpsPositionX = position.x
  1030.     gpsPositionZ = position.y
  1031.     gpsPositionY = position.z
  1032.    
  1033. end
  1034.  
  1035. function setSimFlags(b)
  1036.     sim_mode = b
  1037.     cost_only = b
  1038.     if cmd_line_cost_only then
  1039.         cost_only = true
  1040.     end
  1041. end
  1042.  
  1043. function simulationCheck() -- checks state of the simulation
  1044.     if sim_mode then
  1045.         if compareProgress() then
  1046.             setSimFlags(false) -- If we're caught up, un-set flags
  1047.         else
  1048.             setSimFlags(true)  -- If not caught up, just re-affirm that the flags are set
  1049.         end
  1050.     end
  1051. end
  1052.  
  1053. function continueQuery()
  1054.     if cmd_line_resume then
  1055.          return true
  1056.     else
  1057.          if not cmd_line then
  1058.              writeOut("Do you want to continue the last job?")
  1059.              local yes = io.read()
  1060.              if yes == "y" then
  1061.                  return true
  1062.              else
  1063.                  return false
  1064.              end
  1065.          end
  1066.     end
  1067. end
  1068.  
  1069. function progressUpdate()  -- This ONLY updates the local table variable.  Writing is handled above. -- I want to change this to allow for any number of params
  1070.     progTable = {shape = choice, enderchestRefilling = tempProgTable.enderchestRefilling, param1 = tempProgTable.param1, param2 = tempProgTable.param2, param3 = tempProgTable.param3, param4 = tempProgTable.param4, x = positionX, y = positionY, z = positionZ, facing = facing, blocks = blocks}
  1071.     if not sim_mode then
  1072.         writeProgress()
  1073.     end
  1074. end
  1075.  
  1076.  -- Command Line
  1077. function checkCommandLine() --True if arguments were passed
  1078.     if #argTable > 0 then
  1079.         cmd_line = true
  1080.         return true
  1081.     else
  1082.         cmd_line = false
  1083.         return false
  1084.     end
  1085. end
  1086.  
  1087. function needsHelp() -- True if -h is passed
  1088.     for i, v in pairs(argTable) do
  1089.         if v == "-h" or v == "-help" or v == "--help" then
  1090.             return true
  1091.         else
  1092.             return false
  1093.         end
  1094.     end
  1095. end
  1096.  
  1097. function setFlagsFromCommandLine() -- Sets count_only, chain_next_shape, and sim_mode
  1098.     for i, v in pairs(argTable) do
  1099.         if v == "-c" or v == "-cost" or v == "--cost" then
  1100.             cost_only = true
  1101.             cmd_line_cost_only = true
  1102.             writeOut("Cost only mode")
  1103.         end
  1104.         if v == "-z" or v == "-chain" or v == "--chain" then
  1105.             chain_next_shape = true
  1106.             writeOut("Chained shape mode")
  1107.         end
  1108.         if v == "-r" or v == "-resume" or v == "--resume" then
  1109.             cmd_line_resume = true
  1110.             writeOut("Resuming")
  1111.         end
  1112.     end
  1113. end
  1114.  
  1115. function setTableFromCommandLine() -- Sets progTable and tempProgTable from command line arguments
  1116.     progTable.shape = argTable[1]
  1117.     tempProgTable.shape = argTable[1]
  1118.     local paramName = "param"
  1119.     local paramName2 = paramName
  1120.     for i = 2, #argTable do
  1121.         local addOn = tostring(i - 1)
  1122.         paramName2 = paramName .. addOn
  1123.         progTable[paramName2] = argTable[i]
  1124.         tempProgTable[paramName2] = argTable[i]
  1125.     end
  1126. end
  1127.  
  1128. -- Menu, Drawing and Main functions
  1129.  
  1130. function choiceFunction()
  1131.     if sim_mode == false and cmd_line == false then -- If we are NOT resuming progress
  1132.         choice = io.read()
  1133.         choice = string.lower(choice) -- All checks are aginst lower case words so this is to ensure that
  1134.         tempProgTable = {shape = choice}
  1135.         progTable = {shape = choice}
  1136.         if choice == "next" then
  1137.             WriteMenu2()
  1138.             choice = io.read()
  1139.             choice = string.lower(choice) -- All checks are aginst lower case words so this is to ensure that
  1140.         end
  1141.         if choice == "end" or choice == "exit" then
  1142.             writeOut("Goodbye.")
  1143.             return
  1144.         end
  1145.         if choice == "help" then
  1146.             showHelp()
  1147.             return
  1148.         end
  1149.         if choice == "credits" then
  1150.             showCredits()
  1151.             return
  1152.         end
  1153.         writeOut("Building a "..choice)
  1154.         local yes = getInput("string","Want to just calculate the cost?","y","n")
  1155.         if yes == 'y' then
  1156.             cost_only = true
  1157.         end
  1158.         local yes = getInput("string","Want turtle to return to start after build?","y","n")
  1159.         if yes == 'y' then
  1160.             returntohome = true
  1161.         end
  1162.         local yes = getInput("string","Want the turtle to refill from enderchest (slot 16)?","y","n")
  1163.         if yes == 'y' then
  1164.             enderchestRefilling = true
  1165.             tempProgTable.enderchestRefilling = true;
  1166.         end
  1167.     elseif sim_mode == true then -- If we ARE resuming progress
  1168.         tempProgTable = readProgress()
  1169.         choice = tempProgTable.shape
  1170.         choice = string.lower(choice) -- All checks are aginst lower case words so this is to ensure that
  1171.         enderchestRefilling =  tempProgTable.enderchestRefilling
  1172.     elseif cmd_line == true then -- If running from command line
  1173.         choice = tempProgTable.shape
  1174.         choice = string.lower(choice) -- All checks are aginst lower case words so this is to ensure that
  1175.         enderchestRefilling =  tempProgTable.enderchestRefilling
  1176.         writeOut("Building a "..choice)
  1177.     end
  1178.     if not cost_only then
  1179.         turtle.select(1)
  1180.         activeslot = 1
  1181.         if turtle.getItemCount(activeslot) == 0 then
  1182.             if resupply then
  1183.                 writeOut("Please put building blocks in the first slot.")
  1184.             else
  1185.                 writeOut("Please put building blocks in the first slot (and more if you need them)")
  1186.             end
  1187.             while turtle.getItemCount(activeslot) == 0 do
  1188.                 os.sleep(2)
  1189.             end
  1190.         end
  1191.     else
  1192.         activeslot = 1
  1193.     end
  1194.     -- shape selection if cascade
  1195.     if choice == "rectangle" then
  1196.         local depth = 0
  1197.         local width = 0
  1198.         if sim_mode == false and cmd_line == false then
  1199.             depth = getInput("int","How deep does it need to be?")
  1200.             width = getInput("int","How wide does it need to be?")
  1201.         elseif sim_mode == true or cmd_line == true then
  1202.             depth = tempProgTable.param1
  1203.             width = tempProgTable.param2
  1204.         end
  1205.         tempProgTable.param1 = depth
  1206.         tempProgTable.param2 = width
  1207.         progTable = {param1 = depth, param2 = width} -- THIS is here because we NEED to update the local table!
  1208.         rectangle(depth, width)
  1209.     end
  1210.     if choice == "square" then
  1211.         local sideLength
  1212.         if sim_mode == false and cmd_line == false then
  1213.             sideLength = getInput("int","What depth/width does it need to be?")
  1214.         elseif sim_mode == true or cmd_line == true then
  1215.             sideLength = tempProgTable.param1
  1216.         end
  1217.         tempProgTable.param1 = sideLength
  1218.         progTable = {param1 = sideLength}
  1219.         square(sideLength)
  1220.     end
  1221.     if choice == "line" then
  1222.         local lineLength = 0
  1223.         if sim_mode == false and cmd_line == false then
  1224.             lineLength = getInput("int","How long does it need to be?")
  1225.         elseif sim_mode == true or cmd_line == true then
  1226.             lineLength = tempProgTable.param1
  1227.         end
  1228.         tempProgTable.param1 = lineLength
  1229.         progTable = {param1 = lineLength}
  1230.         line(lineLength)
  1231.     end
  1232.     if choice == "wall" then
  1233.     local depth = 0
  1234.     local height = 0
  1235.         if sim_mode == false and cmd_line == false then
  1236.             depth = getInput("int","How deep does it need to be?")
  1237.             height = getInput("int","How high does it need to be?")
  1238.         elseif sim_mode == true or cmd_line == true then
  1239.             depth = tempProgTable.param1
  1240.             height = tempProgTable.param2
  1241.         end        
  1242.         tempProgTable.param1 = depth
  1243.         tempProgTable.param2 = height
  1244.         progTable = {param1 = depth, param2 = height}
  1245.         wall(depth, height)
  1246.     end
  1247.     if choice == "platform" then
  1248.         local depth = 0
  1249.         local width = 0
  1250.         if sim_mode == false and cmd_line == false then
  1251.             depth = getInput("int","How deep does it need to be?")
  1252.             width = getInput("int","How wide does it need to be?")
  1253.         elseif sim_mode == true or cmd_line == true then
  1254.             depth = tempProgTable.param1   
  1255.             width = tempProgTable.param2       
  1256.         end    
  1257.         tempProgTable.param1 = depth
  1258.         tempProgTable.param2 = width
  1259.         progTable = {param1 = depth, param2 = width}
  1260.         platform(width, depth)
  1261.     end
  1262.     if choice == "stair" then
  1263.         local width = 0
  1264.         local height = 0
  1265.         if sim_mode == false and cmd_line == false then
  1266.             width = getInput("int","How wide does it need to be?")
  1267.             height = getInput("int","How high does it need to be?")
  1268.         elseif sim_mode == true or cmd_line == true then
  1269.             width = tempProgTable.param1
  1270.             height = tempProgTable.param2
  1271.         end
  1272.         tempProgTable.param1 = width
  1273.         tempProgTable.param2 = height
  1274.         progTable = {param1 = width, param2 = height}
  1275.         stair(width, height)
  1276.         special_chain = true
  1277.     end
  1278.     if choice == "cuboid" then
  1279.         local depth = 0
  1280.         local width = 0
  1281.         local height = 0
  1282.         local hollow = ""
  1283.         if sim_mode == false and cmd_line == false then
  1284.             depth = getInput("int","How deep does it need to be?")
  1285.             width = getInput("int","How wide does it need to be?")
  1286.             height = getInput("int","How high does it need to be?")
  1287.             hollow = getInput("string","Does it need to be hollow?","y","n")
  1288.         elseif sim_mode == true or cmd_line == true then
  1289.             depth = tempProgTable.param1
  1290.             width = tempProgTable.param2
  1291.             height = tempProgTable.param3
  1292.             hollow = tempProgTable.param4
  1293.         end
  1294.         tempProgTable.param1 = depth
  1295.         tempProgTable.param2 = width
  1296.         tempProgTable.param3 = height
  1297.         tempProgTable.param4 = hollow
  1298.         if height < 3 then
  1299.             height = 3
  1300.         end
  1301.         if depth < 3 then
  1302.             depth = 3
  1303.         end
  1304.         if width < 3 then
  1305.             width = 3
  1306.         end
  1307.         progTable = {param1 = depth, param2 = width, param3 = height}
  1308.         cuboid(depth, width, height, hollow)
  1309.     end
  1310.     if choice == "1/2-sphere" or choice == "1/2 sphere" then
  1311.         local diameter = 0
  1312.         local half = ""
  1313.         if sim_mode == false and cmd_line == false then
  1314.             diameter = getInput("int","What diameter does it need to be?")
  1315.             half = getInput("string","What half of the sphere does it need to be?","bottom","top")
  1316.         elseif sim_mode == true or cmd_line == true then
  1317.             diameter = tempProgTable.param1
  1318.             half = tempProgTable.param2
  1319.         end
  1320.         tempProgTable.param1 = diameter
  1321.         tempProgTable.param2 = half
  1322.         progTable = {param1 = diameter, param2 = half}
  1323.         if half == "bottom" then
  1324.             dome("bowl", diameter)
  1325.         else
  1326.             dome("dome", diameter)
  1327.         end
  1328.     end
  1329.     if choice == "dome" then
  1330.         local diameter = 0
  1331.         if sim_mode == false and cmd_line == false then
  1332.             diameter = getInput("int","What diameter does it need to be?")
  1333.         elseif sim_mode == true or cmd_line == true then
  1334.             diameter = tempProgTable.param1
  1335.         end
  1336.         tempProgTable.param1 = diameter
  1337.         progTable = {param1 = diameter}
  1338.         dome("dome", diameter)
  1339.     end
  1340.     if choice == "bowl" then
  1341.         local diameter = 0
  1342.         if sim_mode == false and cmd_line == false then
  1343.             diameter = getInput("int","What diameter does it need to be?")
  1344.         elseif sim_mode == true or cmd_line == true then
  1345.             diameter = tempProgTable.param1
  1346.         end
  1347.         tempProgTable.param1 = diameter
  1348.         progTable = {param1 = diameter}
  1349.         dome("bowl", diameter)
  1350.     end
  1351.     if choice == "circle" then
  1352.         local diameter = 0
  1353.         if sim_mode == false and cmd_line == false then
  1354.             diameter = getInput("int","What diameter does it need to be?")
  1355.         elseif sim_mode == true or cmd_line == true then
  1356.             diameter = tempProgTable.param1
  1357.         end
  1358.         tempProgTable.param1 = diameter
  1359.         progTable = {param1 = diameter}
  1360.         circle(diameter)
  1361.     end
  1362.     if choice == "cylinder" then
  1363.         local diameter = 0
  1364.         local height = 0
  1365.         if sim_mode == false and cmd_line == false then
  1366.             diameter = getInput("int","What diameter does it need to be?")
  1367.             height = getInput("int","How high does it need to be?")
  1368.         elseif sim_mode == true or cmd_line == true then
  1369.             diameter = tempProgTable.param1
  1370.             height = tempProgTable.param2
  1371.         end
  1372.         tempProgTable.param1 = diameter
  1373.         tempProgTable.param2 = height
  1374.         progTable = {param1 = diameter, param2 = height}
  1375.         cylinder(diameter, height)
  1376.     end
  1377.     if choice == "pyramid" then
  1378.         local length = 0
  1379.         local hollow = ""
  1380.         if sim_mode == false and cmd_line == false then
  1381.             length = getInput("int","What depth/width does it need to be?")
  1382.             hollow = getInput("string","Does it need to be hollow?","y","n")
  1383.         elseif sim_mode == true or cmd_line == true then
  1384.             length = tempProgTable.param1
  1385.             hollow = tempProgTable.param2
  1386.         end
  1387.         tempProgTable.param1 = length
  1388.         tempProgTable.param2 = hollow
  1389.         progTable = {param1 = length, param2 = hollow}
  1390.         pyramid(length, hollow)
  1391.     end
  1392.     if choice == "sphere" then
  1393.         local diameter = 0
  1394.         if sim_mode == false and cmd_line == false then
  1395.             diameter = getInput("int","What diameter does it need to be?")
  1396.         elseif sim_mode == true or cmd_line == true then
  1397.             diameter = tempProgTable.param1
  1398.         end
  1399.         tempProgTable.param1 = diameter
  1400.         progTable = {param1 = diameter}
  1401.         dome("sphere", diameter)
  1402.     end
  1403.     if choice == "hexagon" then
  1404.         local length = 0
  1405.         if sim_mode == false and cmd_line == false then
  1406.             length = getInput("int","How long does each side need to be?")
  1407.         elseif sim_mode == true or cmd_line == true then
  1408.             length = tempProgTable.param1
  1409.         end
  1410.         tempProgTable.param1 = length
  1411.         progTable = {param1 = length}
  1412.         hexagon(length)
  1413.     end
  1414.     if choice == "octagon" then
  1415.         local length = 0
  1416.         if sim_mode == false and cmd_line == false then
  1417.             length = getInput("int","How long does each side need to be?")
  1418.         elseif sim_mode == true or cmd_line == true then
  1419.             length = tempProgTable.param1
  1420.         end
  1421.         tempProgTable.param1 = length
  1422.         progTable = {param1 = length}
  1423.         octagon(length)
  1424.     end
  1425.     if choice == "6-prism" or choice == "6 prism" then
  1426.         local length = 0
  1427.         local height = 0
  1428.         if sim_mode == false and cmd_line == false then
  1429.             length = getInput("int","How long does each side need to be?")
  1430.             height = getInput("int","What height does it need to be?")
  1431.         elseif sim_mode == true or cmd_line == true then
  1432.             length = tempProgTable.param1
  1433.             height = tempProgTable.param2
  1434.         end
  1435.         tempProgTable.param1 = length
  1436.         tempProgTable.param2 = height
  1437.         progTable = {param1 = length, param2 = height}
  1438.         sixprism(length, height)
  1439.     end
  1440.     if choice == "8-prism" or choice == "8 prism" then
  1441.         local length = 0
  1442.         local height = 0
  1443.         if sim_mode == false and cmd_line == false then
  1444.             length = getInput("int","How long does each side need to be?")
  1445.             height = getInput("int","What height does it need to be?")
  1446.         elseif sim_mode == true or cmd_line == true then
  1447.             length = tempProgTable.param1
  1448.             height = tempProgTable.param2
  1449.         end
  1450.         tempProgTable.param1 = length
  1451.         tempProgTable.param2 = height
  1452.         progTable = {param1 = length, param2 = height}
  1453.         eightprism(length, height)
  1454.     end
  1455.     if returntohome then
  1456.         goHome() -- After all shape building has finished
  1457.     end
  1458.     writeOut("Done") -- Saves a few lines when put here rather than in each if statement
  1459. end
  1460.  
  1461. function WriteMenu()
  1462.     term.clear()
  1463.     term.setCursorPos(1, 1)
  1464.     writeOut("Shape Maker 1.5 by Keridos/Happydude/pokemane")
  1465.     if resupply then                    -- Any ideas to make this more compact/betterlooking (in terms of code)?
  1466.         writeOut("Resupply Mode Active")
  1467.     elseif (resupply and can_use_gps) then
  1468.         writeOut("Resupply and GPS Mode Active")
  1469.     elseif can_use_gps then
  1470.         writeOut("GPS Mode Active")
  1471.     else
  1472.         writeOut("")
  1473.     end
  1474.     if not cmd_line then
  1475.         writeOut("What should be built? [page 1/2]");
  1476.         writeOut("next for page 2")
  1477.         writeOut("+---------+-----------+-------+-------+")
  1478.         writeOut("| square  | rectangle | wall  | line  |")
  1479.         writeOut("| cylinder| platform  | stair | cuboid|")
  1480.         writeOut("| pyramid | 1/2-sphere| circle| next  |")
  1481.         writeOut("+---------+-----------+-------+-------+")
  1482.         writeOut("")
  1483.     end
  1484. end
  1485.  
  1486. function WriteMenu2()
  1487.     term.clear()
  1488.     term.setCursorPos(1, 1)
  1489.     writeOut("Shape Maker 1.5 by Keridos/Happydude/pokemane")
  1490.     if resupply then                    -- Any ideas to make this more compact/betterlooking (in terms of code)?
  1491.         writeOut("Resupply Mode Active")
  1492.     elseif (resupply and can_use_gps) then
  1493.         writeOut("Resupply and GPS Mode Active")
  1494.     elseif can_use_gps then
  1495.         writeOut("GPS Mode Active")
  1496.     else
  1497.         writeOut("")
  1498.     end
  1499.     writeOut("What should be built [page 2/2]?");
  1500.     writeOut("")
  1501.     writeOut("+---------+-----------+-------+-------+")
  1502.     writeOut("| hexagon | octagon   | help  |       |")
  1503.     writeOut("| 6-prism | 8-prism   | end   |       |")
  1504.     writeOut("| sphere  | credits   |       |       |")
  1505.     writeOut("+---------+-----------+-------+-------+")
  1506.     writeOut("")
  1507. end
  1508.  
  1509. function showHelp()
  1510.     writeOut("Usage: shape [shape-type [param1 param2 param3 ...]] [-c] [-h] [-z] [-r]")
  1511.     writeOut("-c: Activate cost only mode")
  1512.     writeOut("-h: Show this page")
  1513.     writeOut("-z: Set chain_next_shape to true, lets you chain together multiple shapes")
  1514.     io.read() -- Pause here
  1515.     writeOut("-r: Resume the last shape if there is a resume file")
  1516.     writeOut("shape-type can be any of the shapes in the menu")
  1517.     writeOut("After shape-type input all of the paramaters for the shape")
  1518.     io.read() -- Pause here, too
  1519. end
  1520.  
  1521. function showCredits()
  1522.     writeOut("Credits for the shape builder:")
  1523.     writeOut("Based on work by Michiel,Vliekkie, and Aeolun")
  1524.     writeOut("Sphere/dome code by pruby")
  1525.     writeOut("Additional improvements by Keridos,Happydude and pokemane")
  1526.     io.read() -- Pause here, too
  1527. end
  1528.  
  1529. function main()
  1530.     if wrapmodules()=="resupply" then
  1531.         linkToRSStation()
  1532.     end
  1533.     if checkCommandLine() then
  1534.         if needsHelp() then
  1535.             showHelp()
  1536.             return -- Close the program after help info is shown
  1537.         end
  1538.         setFlagsFromCommandLine()
  1539.         setTableFromCommandLine()
  1540.     end
  1541.     if (CheckForPrevious()) then  -- Will check to see if there was a previous job and gps is enabled, and if so, ask if the user would like to re-initialize to current progress status
  1542.         if not continueQuery() then -- If the user doesn't want to continue
  1543.             ProgressFileDelete()
  1544.             setSimFlags(false) -- Just to be safe
  1545.             WriteMenu()
  1546.             choiceFunction()
  1547.         else    -- If the user wants to continue
  1548.             setSimFlags(true)
  1549.             choiceFunction()
  1550.         end
  1551.     else
  1552.         setSimFlags(false)
  1553.         WriteMenu()
  1554.         choiceFunction()
  1555.     end
  1556.     if (blocks ~= 0) and (fuel ~= 0) then -- Do not show on help or credits page or when selecting end
  1557.         writeOut("Blocks used: " .. blocks)
  1558.         writeOut("Fuel used: " .. fuel)
  1559.     end
  1560.     ProgressFileDelete() -- Removes file upon successful completion of a job, or completion of a previous job.
  1561.     progTable = {}
  1562.     tempProgTable = {}
  1563. end
  1564.  
  1565. main()
Advertisement
Add Comment
Please, Sign In to add comment