Advertisement
Keridos

ShapeBuilder Beta

Feb 26th, 2014
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 41.55 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 < 3 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 < 3 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(radius)
  618.     width = radius * 2 + 1
  619.     sqrt3 = 3 ^ 0.5
  620.     boundaryRadius = radius + 1.0
  621.     boundary2 = boundaryRadius ^ 2
  622.     z = radius
  623.     cz2 = (radius - z) ^ 2
  624.     limitOffsetY = (boundary2 - cz2) ^ 0.5
  625.     maxOffestY = math.ceil(limitOffsetY)
  626.     -- We do first the +x side, then the -x side to make movement efficient
  627.     for side = 0, 1 do
  628.         -- On the right we go from small y to large y, on the left reversed
  629.         -- This makes us travel clockwise (from below) around each layer
  630.         if (side == 0) then
  631.             yStart = radius - maxOffestY
  632.             yEnd = radius + maxOffestY
  633.             yStep = 1
  634.         else
  635.             yStart = radius + maxOffestY
  636.             yEnd = radius - maxOffestY
  637.             yStep = -1
  638.         end
  639.         for y = yStart, yEnd, yStep do
  640.             cy2 = (radius - y) ^ 2
  641.             remainder2 = (boundary2 - cz2 - cy2)
  642.             if remainder2 >= 0 then
  643.                 -- This is the maximum difference in x from the centre we can be without definitely being outside the radius
  644.                 maxOffsetX = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
  645.                     -- Only do either the +x or -x side
  646.                 if (side == 0) then
  647.                     -- +x side
  648.                     xStart = radius
  649.                     xEnd = radius + maxOffsetX
  650.                 else
  651.                     -- -x side
  652.                     xStart = radius - maxOffsetX
  653.                     xEnd = radius - 1
  654.                 end
  655.                 -- Reverse direction we traverse xs when in -y side
  656.                 if y > radius then
  657.                     temp = xStart
  658.                     xStart = xEnd
  659.                     xEnd = temp
  660.                     xStep = -1
  661.                 else
  662.                     xStep = 1
  663.                 end
  664.                     for x = xStart, xEnd, xStep do
  665.                     cx2 = (radius - x) ^ 2
  666.                     distanceToCentre = (cx2 + cy2 + cz2) ^ 0.5
  667.                     -- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
  668.                     if distanceToCentre < boundaryRadius and distanceToCentre + sqrt3 >= boundaryRadius then
  669.                         offsets = {{0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}
  670.                         for i=1,6 do
  671.                             offset = offsets[i]
  672.                             dx = offset[1]
  673.                             dy = offset[2]
  674.                             dz = offset[3]
  675.                             if ((radius - (x + dx)) ^ 2 + (radius - (y + dy)) ^ 2 + (radius - (z + dz)) ^ 2) ^ 0.5 >= boundaryRadius then
  676.                                 -- This is a point to use
  677.                                 navigateTo(x, y)
  678.                                 placeBlock()
  679.                                 break
  680.                             end
  681.                         end
  682.                     end
  683.                 end
  684.             end
  685.         end
  686.     end
  687. end
  688.  
  689. function dome(typus, radius)
  690.     -- Main dome and sphere building routine
  691.     width = radius * 2 + 1
  692.     sqrt3 = 3 ^ 0.5
  693.     boundaryRadius = radius + 1.0
  694.     boundary2 = boundaryRadius ^ 2
  695.     if typus == "dome" then
  696.         zstart = radius
  697.     elseif typus == "sphere" then
  698.         zstart = 0
  699.     elseif typus == "bowl" then
  700.         zstart = 0
  701.     end
  702.     if typus == "bowl" then
  703.         zend = radius
  704.     else
  705.         zend = width - 1
  706.     end
  707.  
  708.     -- This loop is for each vertical layer through the sphere or dome.
  709.     for z = zstart,zend do
  710.         if not cost_only and z ~= zstart then
  711.             safeUp()
  712.         end
  713.         --writeOut("Layer " .. z)
  714.         cz2 = (radius - z) ^ 2
  715.         limitOffsetY = (boundary2 - cz2) ^ 0.5
  716.         maxOffestY = math.ceil(limitOffsetY)
  717.         -- We do first the +x side, then the -x side to make movement efficient
  718.         for side = 0,1 do
  719.             -- On the right we go from small y to large y, on the left reversed
  720.             -- This makes us travel clockwise (from below) around each layer
  721.             if (side == 0) then
  722.                 yStart = radius - maxOffestY
  723.                 yEnd = radius + maxOffestY
  724.                 yStep = 1
  725.             else
  726.                 yStart = radius + maxOffestY
  727.                 yEnd = radius - maxOffestY
  728.                 yStep = -1
  729.             end
  730.             for y = yStart,yEnd,yStep do
  731.                 cy2 = (radius - y) ^ 2
  732.                 remainder2 = (boundary2 - cz2 - cy2)
  733.                 if remainder2 >= 0 then
  734.                     -- This is the maximum difference in x from the centre we can be without definitely being outside the radius
  735.                     maxOffsetX = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
  736.                     -- Only do either the +x or -x side
  737.                     if (side == 0) then
  738.                         -- +x side
  739.                         xStart = radius
  740.                         xEnd = radius + maxOffsetX
  741.                     else
  742.                         -- -x side
  743.                         xStart = radius - maxOffsetX
  744.                         xEnd = radius - 1
  745.                     end
  746.                     -- Reverse direction we traverse xs when in -y side
  747.                     if y > radius then
  748.                         temp = xStart
  749.                         xStart = xEnd
  750.                         xEnd = temp
  751.                         xStep = -1
  752.                     else
  753.                         xStep = 1
  754.                     end
  755.  
  756.                     for x = xStart,xEnd,xStep do
  757.                         cx2 = (radius - x) ^ 2
  758.                         distanceToCentre = (cx2 + cy2 + cz2) ^ 0.5
  759.                         -- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
  760.                         if distanceToCentre < boundaryRadius and distanceToCentre + sqrt3 >= boundaryRadius then
  761.                             offsets = {{0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}
  762.                             for i=1,6 do
  763.                                 offset = offsets[i]
  764.                                 dx = offset[1]
  765.                                 dy = offset[2]
  766.                                 dz = offset[3]
  767.                                 if ((radius - (x + dx)) ^ 2 + (radius - (y + dy)) ^ 2 + (radius - (z + dz)) ^ 2) ^ 0.5 >= boundaryRadius then
  768.                                     -- This is a point to use
  769.                                     navigateTo(x, y)
  770.                                     placeBlock()
  771.                                     break
  772.                                 end
  773.                             end
  774.                         end
  775.                     end
  776.                 end
  777.             end
  778.         end
  779.     end
  780. end
  781.  
  782. function cylinder(radius, height)
  783.     for i = 1, height do
  784.         circle(radius)
  785.         safeUp()
  786.     end
  787. end
  788.  
  789. function hexagon(sideLength)
  790.     local changeX = sideLength / 2
  791.     local changeY = round(math.sqrt(3) * changeX, 0)
  792.     changeX = round(changeX, 0)
  793.     local counter = 0
  794.  
  795.     navigateTo(changeX, 0)
  796.  
  797.     for currentSide = 1, 6 do
  798.         counter = 0
  799.  
  800.         if currentSide == 1 then
  801.             for placed = 1, sideLength do
  802.                 navigateTo(positionX + 1, positionY)
  803.                 placeBlock()
  804.             end
  805.         elseif currentSide == 2 then
  806.             navigateTo(positionX, positionY + 1)
  807.             while positionY <= changeY do
  808.                 if counter == 0 or counter == 2 or counter == 4 then
  809.                     navigateTo(positionX + 1, positionY)
  810.                 end
  811.                 placeBlock()
  812.                 navigateTo(positionX, positionY + 1)
  813.                 counter = counter + 1
  814.                 if counter == 5 then
  815.                     counter = 0
  816.                 end
  817.             end
  818.         elseif currentSide == 3 then
  819.             while positionY <= (2 * changeY) do
  820.                 if counter == 0 or counter == 2 or counter == 4 then
  821.                     navigateTo(positionX - 1, positionY)
  822.                 end
  823.                 placeBlock()
  824.                 navigateTo(positionX, positionY + 1)
  825.                 counter = counter + 1
  826.                 if counter == 5 then
  827.                     counter = 0
  828.                 end
  829.             end
  830.         elseif currentSide == 4 then
  831.             for placed = 1, sideLength do
  832.                 navigateTo(positionX - 1, positionY)
  833.                 placeBlock()
  834.             end
  835.         elseif currentSide == 5 then
  836.             navigateTo(positionX, positionY - 1)
  837.             while positionY >= changeY do
  838.                 if counter == 0 or counter == 2 or counter == 4 then
  839.                     navigateTo(positionX - 1, positionY)
  840.                 end
  841.                 placeBlock()
  842.                 navigateTo(positionX, positionY - 1)
  843.                 counter = counter + 1
  844.                 if counter == 5 then
  845.                     counter = 0
  846.                 end
  847.             end
  848.         elseif currentSide == 6 then
  849.             while positionY >= 0 do
  850.                 if counter == 0 or counter == 2 or counter == 4 then
  851.                     navigateTo(positionX + 1, positionY)
  852.                 end
  853.                 placeBlock()
  854.                 navigateTo(positionX, positionY - 1)
  855.                 counter = counter + 1
  856.                 if counter == 5 then
  857.                     counter = 0
  858.                 end
  859.             end
  860.         end
  861.     end
  862. end
  863.  
  864. function octagon(sideLength)
  865.     local sideLength2 = sideLength - 1
  866.     local change = round(sideLength2 / math.sqrt(2), 0)
  867.  
  868.     navigateTo(change, 0)
  869.  
  870.     for currentSide = 1, 8 do
  871.         if currentSide == 1 then
  872.             for placed = 1, sideLength2 do
  873.                 navigateTo(positionX + 1, positionY)
  874.                 placeBlock()
  875.             end
  876.         elseif currentSide == 2 then
  877.             for placed = 1, change do
  878.                 navigateTo(positionX + 1, positionY + 1)
  879.                 placeBlock()
  880.             end
  881.         elseif currentSide == 3 then
  882.             for placed = 1, sideLength2 do
  883.                 navigateTo(positionX, positionY + 1)
  884.                 placeBlock()
  885.             end
  886.         elseif currentSide == 4 then
  887.             for placed = 1, change do
  888.                 navigateTo(positionX - 1, positionY + 1)
  889.                 placeBlock()
  890.             end
  891.         elseif currentSide == 5 then
  892.             for placed = 1, sideLength2 do
  893.                 navigateTo(positionX - 1, positionY)
  894.                 placeBlock()
  895.             end
  896.         elseif currentSide == 6 then
  897.             for placed = 1, change do
  898.                 navigateTo(positionX - 1, positionY - 1)
  899.                 placeBlock()
  900.             end
  901.         elseif currentSide == 7 then
  902.         for placed = 1, sideLength2 do
  903.                 navigateTo(positionX, positionY - 1)
  904.                 placeBlock()
  905.             end
  906.         elseif currentSide == 8 then
  907.             for placed = 1, change do
  908.                 navigateTo(positionX + 1, positionY - 1)
  909.                 placeBlock()
  910.             end
  911.         end
  912.     end
  913. end
  914.  
  915. function sixprism(length, height)
  916.     for i = 1, height do
  917.         hexagon(length)
  918.         safeUp()
  919.     end
  920. end
  921.  
  922. function eigthprism(length, height)
  923.     for i = 1, height do
  924.         octagon(length)
  925.         safeUp()
  926.     end
  927. end
  928.  
  929. -- Previous Progress Resuming, Simulation functions, Command Line, and File Backend
  930. -- Will check for a "progress" file.
  931. function CheckForPrevious()
  932.     if fs.exists(progFileName) then
  933.         return true
  934.     else
  935.         return false
  936.     end
  937. end
  938.  
  939. -- 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)
  940. function ProgressFileCreate()
  941.     if not CheckForPrevious() then
  942.         fs.makeDir(progFileName)
  943.         return true
  944.     else
  945.         return false
  946.     end
  947. end
  948.  
  949. -- Deletes the progress file (at the end of the project, also at beginning if user chooses to delete old progress)
  950. function ProgressFileDelete()
  951.     if fs.exists(progFileName) then
  952.         fs.delete(progFileName)
  953.         return true
  954.     else
  955.         return false
  956.     end
  957. end
  958.  
  959. -- To read the shape params from the file.  Shape type, and input params (e.g. "dome" and radius)
  960. function ReadShapeParams()
  961.     -- TODO. Unneeded for now, can just use the table elements directly
  962. end
  963.  
  964. function WriteShapeParams(...) -- The ... lets it take any number of arguments and stores it to the table arg{} | This is still unused anywhere
  965.     local paramTable = arg
  966.     local paramName = "param"
  967.     local paramName2 = paramName
  968.     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!
  969.         paramName2 = paramName .. i
  970.         tempProgTable[paramName2] = v
  971.         progTable[paramName2] = v
  972.     end
  973. end
  974.  
  975. -- function to write the progress to the file (x, y, z)
  976. function writeProgress()
  977.     local progFile
  978.     local progString = ""
  979.     if not (sim_mode or cost_only) then
  980.         progString = textutils.serialize(progTable) -- Put in here to save processing time when in cost_only
  981.         progFile = fs.open(progFileName, "w")
  982.         progFile.write(progString)
  983.         progFile.close()
  984.     end
  985.  
  986. end
  987.  
  988. -- Reads progress from file (shape, x, y, z, facing, blocks, param1, param2, param3)
  989. function readProgress()
  990.     local progFile = fs.open(progFileName, "r")
  991.     local readProgTable = textutils.unserialize(progFile.readAll())
  992.     progFile.close()
  993.     return readProgTable
  994. end
  995.  
  996. -- compares the progress read from the file to the current sim progress.  needs all four params
  997. function compareProgress()
  998.     local progTableIn = progTable
  999.     local readProgTable = readProgress()
  1000.     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
  1001.         writeOut("All caught up!")
  1002.         return true -- We're caught up!
  1003.     else
  1004.         return false -- Not there yet...
  1005.     end
  1006. end
  1007.  
  1008. function getGPSInfo() -- TODO: finish this
  1009.     position = gps.locate()
  1010.     gpsPositionX = position.x
  1011.     gpsPositionZ = position.y
  1012.     gpsPositionY = position.z
  1013.    
  1014. end
  1015.  
  1016. function setSimFlags(b)
  1017.     sim_mode = b
  1018.     cost_only = b
  1019.     if cmd_line_cost_only then
  1020.         cost_only = true
  1021.     end
  1022. end
  1023.  
  1024. function simulationCheck() -- checks state of the simulation
  1025.     if sim_mode then
  1026.         if compareProgress() then
  1027.             setSimFlags(false) -- If we're caught up, un-set flags
  1028.         else
  1029.             setSimFlags(true)  -- If not caught up, just re-affirm that the flags are set
  1030.         end
  1031.     end
  1032. end
  1033.  
  1034. function continueQuery()
  1035.     if cmd_line_resume then
  1036.          return true
  1037.     else
  1038.          if not cmd_line then
  1039.              writeOut("Do you want to continue the last job?")
  1040.              local yes = io.read()
  1041.              if yes == "y" then
  1042.                  return true
  1043.              else
  1044.                  return false
  1045.              end
  1046.          end
  1047.     end
  1048. end
  1049.  
  1050. 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
  1051.     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}
  1052.     if not sim_mode then
  1053.         writeProgress()
  1054.     end
  1055. end
  1056.  
  1057.  -- Command Line
  1058. function checkCommandLine() --True if arguments were passed
  1059.     if #argTable > 0 then
  1060.         cmd_line = true
  1061.         return true
  1062.     else
  1063.         cmd_line = false
  1064.         return false
  1065.     end
  1066. end
  1067.  
  1068. function needsHelp() -- True if -h is passed
  1069.     for i, v in pairs(argTable) do
  1070.         if v == "-h" or v == "-help" or v == "--help" then
  1071.             return true
  1072.         else
  1073.             return false
  1074.         end
  1075.     end
  1076. end
  1077.  
  1078. function setFlagsFromCommandLine() -- Sets count_only, chain_next_shape, and sim_mode
  1079.     for i, v in pairs(argTable) do
  1080.         if v == "-c" or v == "-cost" or v == "--cost" then
  1081.             cost_only = true
  1082.             cmd_line_cost_only = true
  1083.             writeOut("Cost only mode")
  1084.         end
  1085.         if v == "-z" or v == "-chain" or v == "--chain" then
  1086.             chain_next_shape = true
  1087.             writeOut("Chained shape mode")
  1088.         end
  1089.         if v == "-r" or v == "-resume" or v == "--resume" then
  1090.             cmd_line_resume = true
  1091.             writeOut("Resuming")
  1092.         end
  1093.     end
  1094. end
  1095.  
  1096. function setTableFromCommandLine() -- Sets progTable and tempProgTable from command line arguments
  1097.     progTable.shape = argTable[1]
  1098.     tempProgTable.shape = argTable[1]
  1099.     local paramName = "param"
  1100.     local paramName2 = paramName
  1101.     for i = 2, #argTable do
  1102.         local addOn = tostring(i - 1)
  1103.         paramName2 = paramName .. addOn
  1104.         progTable[paramName2] = argTable[i]
  1105.         tempProgTable[paramName2] = argTable[i]
  1106.     end
  1107. end
  1108.  
  1109. -- Menu, Drawing and Main functions
  1110.  
  1111. function choiceFunction()
  1112.     if sim_mode == false and cmd_line == false then -- If we are NOT resuming progress
  1113.         choice = io.read()
  1114.         choice = string.lower(choice) -- All checks are aginst lower case words so this is to ensure that
  1115.         tempProgTable = {shape = choice}
  1116.         progTable = {shape = choice}
  1117.         if choice == "next" then
  1118.             WriteMenu2()
  1119.             choice = io.read()
  1120.             choice = string.lower(choice) -- All checks are aginst lower case words so this is to ensure that
  1121.         end
  1122.         if choice == "end" or choice == "exit" then
  1123.             writeOut("Goodbye.")
  1124.             return
  1125.         end
  1126.         if choice == "help" then
  1127.             showHelp()
  1128.             return
  1129.         end
  1130.         if choice == "credits" then
  1131.             showCredits()
  1132.             return
  1133.         end
  1134.         writeOut("Building a "..choice)
  1135.         local yes = getInput("string","Want to just calculate the cost?","y","n")
  1136.         if yes == 'y' then
  1137.             cost_only = true
  1138.         end
  1139.         local yes = getInput("string","Want turtle to return to start after build?","y","n")
  1140.         if yes == 'y' then
  1141.             returntohome = true
  1142.         end
  1143.         local yes = getInput("string","Want the turtle to refill from enderchest (slot 16)?","y","n")
  1144.         if yes == 'y' then
  1145.             enderchestRefilling = true
  1146.             tempProgTable.enderchestRefilling = true;
  1147.         end
  1148.     elseif sim_mode == true then -- If we ARE resuming progress
  1149.         tempProgTable = readProgress()
  1150.         choice = tempProgTable.shape
  1151.         choice = string.lower(choice) -- All checks are aginst lower case words so this is to ensure that
  1152.         enderchestRefilling =  tempProgTable.enderchestRefilling
  1153.     elseif cmd_line == true then -- If running from command line
  1154.         choice = tempProgTable.shape
  1155.         choice = string.lower(choice) -- All checks are aginst lower case words so this is to ensure that
  1156.         enderchestRefilling =  tempProgTable.enderchestRefilling
  1157.         writeOut("Building a "..choice)
  1158.     end
  1159.     if not cost_only then
  1160.         turtle.select(1)
  1161.         activeslot = 1
  1162.         if turtle.getItemCount(activeslot) == 0 then
  1163.             if resupply then
  1164.                 writeOut("Please put building blocks in the first slot.")
  1165.             else
  1166.                 writeOut("Please put building blocks in the first slot (and more if you need them)")
  1167.             end
  1168.             while turtle.getItemCount(activeslot) == 0 do
  1169.                 os.sleep(2)
  1170.             end
  1171.         end
  1172.     else
  1173.         activeslot = 1
  1174.     end
  1175.     -- shape selection if cascade
  1176.     if choice == "rectangle" then
  1177.         local depth = 0
  1178.         local width = 0
  1179.         if sim_mode == false and cmd_line == false then
  1180.             depth = getInput("int","How deep does it need to be?")
  1181.             width = getInput("int","How wide does it need to be?")
  1182.         elseif sim_mode == true or cmd_line == true then
  1183.             depth = tempProgTable.param1
  1184.             width = tempProgTable.param2
  1185.         end
  1186.         tempProgTable.param1 = depth
  1187.         tempProgTable.param2 = width
  1188.         progTable = {param1 = depth, param2 = width} -- THIS is here because we NEED to update the local table!
  1189.         rectangle(depth, width)
  1190.     end
  1191.     if choice == "square" then
  1192.         local sideLength
  1193.         if sim_mode == false and cmd_line == false then
  1194.             writeOut("What depth/width does it need to be?")
  1195.             sideLength = io.read()
  1196.         elseif sim_mode == true or cmd_line == true then
  1197.             sideLength = tempProgTable.param1
  1198.         end
  1199.         tempProgTable.param1 = sideLength
  1200.         progTable = {param1 = sideLength}
  1201.         square(sideLength)
  1202.     end
  1203.     if choice == "line" then
  1204.         local lineLength = 0
  1205.         if sim_mode == false and cmd_line == false then
  1206.             lineLength = getInput("int","How long does it need to be?")
  1207.         elseif sim_mode == true or cmd_line == true then
  1208.             lineLength = tempProgTable.param1
  1209.         end
  1210.         tempProgTable.param1 = lineLength
  1211.         progTable = {param1 = lineLength}
  1212.         line(lineLength)
  1213.     end
  1214.     if choice == "wall" then
  1215.     local depth = 0
  1216.     local height = 0
  1217.         if sim_mode == false and cmd_line == false then
  1218.             depth = getInput("int","How deep does it need to be?")
  1219.             height = getInput("int","How high does it need to be?")
  1220.         elseif sim_mode == true or cmd_line == true then
  1221.             depth = tempProgTable.param1
  1222.             height = tempProgTable.param2
  1223.         end        
  1224.         tempProgTable.param1 = depth
  1225.         tempProgTable.param2 = height
  1226.         progTable = {param1 = depth, param2 = height}
  1227.         wall(depth, height)
  1228.     end
  1229.     if choice == "platform" then
  1230.         local depth = 0
  1231.         local width = 0
  1232.         if sim_mode == false and cmd_line == false then
  1233.             depth = getInput("int","How deep does it need to be?")
  1234.             width = getInput("int","How wide does it need to be?")
  1235.         elseif sim_mode == true or cmd_line == true then
  1236.             depth = tempProgTable.param1   
  1237.             width = tempProgTable.param2       
  1238.         end    
  1239.         tempProgTable.param1 = depth
  1240.         tempProgTable.param2 = width
  1241.         progTable = {param1 = depth, param2 = width}
  1242.         platform(width, depth)
  1243.     end
  1244.     if choice == "stair" then
  1245.         local width = 0
  1246.         local height = 0
  1247.         if sim_mode == false and cmd_line == false then
  1248.             width = getInput("int","How wide does it need to be?")
  1249.             height = getInput("int","How high does it need to be?")
  1250.         elseif sim_mode == true or cmd_line == true then
  1251.             width = tempProgTable.param1
  1252.             height = tempProgTable.param2
  1253.         end
  1254.         tempProgTable.param1 = width
  1255.         tempProgTable.param2 = height
  1256.         progTable = {param1 = width, param2 = height}
  1257.         stair(width, height)
  1258.         special_chain = true
  1259.     end
  1260.     if choice == "cuboid" then
  1261.         local depth = 0
  1262.         local width = 0
  1263.         local height = 0
  1264.         local hollow = ""
  1265.         if sim_mode == false and cmd_line == false then
  1266.             depth = getInput("int","How deep does it need to be?")
  1267.             width = getInput("int","How wide does it need to be?")
  1268.             height = getInput("int","How high does it need to be?")
  1269.             hollow = getInput("string","Does it need to be hollow?","y","n")
  1270.         elseif sim_mode == true or cmd_line == true then
  1271.             depth = tempProgTable.param1
  1272.             width = tempProgTable.param2
  1273.             height = tempProgTable.param3
  1274.             hollow = tempProgTable.param4
  1275.         end
  1276.         tempProgTable.param1 = depth
  1277.         tempProgTable.param2 = width
  1278.         tempProgTable.param3 = height
  1279.         tempProgTable.param4 = hollow
  1280.         if height < 3 then
  1281.             height = 3
  1282.         end
  1283.         if depth < 3 then
  1284.             depth = 3
  1285.         end
  1286.         if width < 3 then
  1287.             width = 3
  1288.         end
  1289.         progTable = {param1 = depth, param2 = width, param3 = height}
  1290.         cuboid(depth, width, height, hollow)
  1291.     end
  1292.     if choice == "1/2-sphere" or choice == "1/2 sphere" then
  1293.         local radius = 0
  1294.         local half = ""
  1295.         if sim_mode == false and cmd_line == false then
  1296.             radius = getInput("int","What radius does it need to be?")
  1297.             half = getInput("string","What half of the sphere does it need to be?","bottom","top")
  1298.         elseif sim_mode == true or cmd_line == true then
  1299.             radius = tempProgTable.param1
  1300.             half = tempProgTable.param2
  1301.         end
  1302.         tempProgTable.param1 = radius
  1303.         tempProgTable.param2 = half
  1304.         progTable = {param1 = radius, param2 = half}
  1305.         if half == "bottom" then
  1306.             dome("bowl", radius)
  1307.         else
  1308.             dome("dome", radius)
  1309.         end
  1310.     end
  1311.     if choice == "dome" then
  1312.         local radius = 0
  1313.         if sim_mode == false and cmd_line == false then
  1314.             radius = getInput("int","What radius does it need to be?")
  1315.         elseif sim_mode == true or cmd_line == true then
  1316.             radius = tempProgTable.param1
  1317.         end
  1318.         tempProgTable.param1 = radius
  1319.         progTable = {param1 = radius}
  1320.         dome("dome", radius)
  1321.     end
  1322.     if choice == "bowl" then
  1323.         local radius = 0
  1324.         if sim_mode == false and cmd_line == false then
  1325.             radius = getInput("int","What radius does it need to be?")
  1326.         elseif sim_mode == true or cmd_line == true then
  1327.             radius = tempProgTable.param1
  1328.         end
  1329.         tempProgTable.param1 = radius
  1330.         progTable = {param1 = radius}
  1331.         dome("bowl", radius)
  1332.     end
  1333.     if choice == "circle" then
  1334.         local radius = 0
  1335.         if sim_mode == false and cmd_line == false then
  1336.             radius = getInput("int","What radius does it need to be?")
  1337.         elseif sim_mode == true or cmd_line == true then
  1338.             radius = tempProgTable.param1
  1339.         end
  1340.         tempProgTable.param1 = radius
  1341.         progTable = {param1 = radius}
  1342.         circle(radius)
  1343.     end
  1344.     if choice == "cylinder" then
  1345.         local radius = 0
  1346.         local height = 0
  1347.         if sim_mode == false and cmd_line == false then
  1348.             radius = getInput("int","What radius does it need to be?")
  1349.             height = getInput("int","How high does it need to be?")
  1350.         elseif sim_mode == true or cmd_line == true then
  1351.             radius = tempProgTable.param1
  1352.             height = tempProgTable.param2
  1353.         end
  1354.         tempProgTable.param1 = radius
  1355.         tempProgTable.param2 = height
  1356.         progTable = {param1 = radius, param2 = height}
  1357.         cylinder(radius, height)
  1358.     end
  1359.     if choice == "pyramid" then
  1360.         local length = 0
  1361.         local hollow = ""
  1362.         if sim_mode == false and cmd_line == false then
  1363.             length = getInput("int","What depth/width does it need to be?")
  1364.             hollow = getInput("string","Does it need to be hollow?","y","n")
  1365.         elseif sim_mode == true or cmd_line == true then
  1366.             length = tempProgTable.param1
  1367.             hollow = tempProgTable.param2
  1368.         end
  1369.         tempProgTable.param1 = length
  1370.         tempProgTable.param2 = hollow
  1371.         progTable = {param1 = length, param2 = hollow}
  1372.         pyramid(length, hollow)
  1373.     end
  1374.     if choice == "sphere" then
  1375.         local radius = 0
  1376.         if sim_mode == false and cmd_line == false then
  1377.             radius = getInput("int","What radius does it need to be?")
  1378.         elseif sim_mode == true or cmd_line == true then
  1379.             radius = tempProgTable.param1
  1380.         end
  1381.         tempProgTable.param1 = radius
  1382.         progTable = {param1 = radius}
  1383.         dome("sphere", radius)
  1384.     end
  1385.     if choice == "hexagon" then
  1386.         local length = 0
  1387.         if sim_mode == false and cmd_line == false then
  1388.             length = getInput("int","How long does each side need to be?")
  1389.         elseif sim_mode == true or cmd_line == true then
  1390.             length = tempProgTable.param1
  1391.         end
  1392.         tempProgTable.param1 = length
  1393.         progTable = {param1 = length}
  1394.         hexagon(length)
  1395.     end
  1396.     if choice == "octagon" then
  1397.         local length = 0
  1398.         if sim_mode == false and cmd_line == false then
  1399.             length = getInput("int","How long does each side need to be?")
  1400.         elseif sim_mode == true or cmd_line == true then
  1401.             length = tempProgTable.param1
  1402.         end
  1403.         tempProgTable.param1 = length
  1404.         progTable = {param1 = length}
  1405.         octagon(length)
  1406.     end
  1407.     if choice == "6-prism" or choice == "6 prism" then
  1408.         local length = 0
  1409.         local height = 0
  1410.         if sim_mode == false and cmd_line == false then
  1411.             length = getInput("int","How long does each side need to be?")
  1412.             height = getInput("int","What height does it need to be?")
  1413.         elseif sim_mode == true or cmd_line == true then
  1414.             length = tempProgTable.param1
  1415.             height = tempProgTable.param2
  1416.         end
  1417.         tempProgTable.param1 = length
  1418.         tempProgTable.param2 = height
  1419.         progTable = {param1 = length, param2 = height}
  1420.         sixprism(length, height)
  1421.     end
  1422.     if choice == "8-prism" or choice == "8 prism" then
  1423.         local length = 0
  1424.         local height = 0
  1425.         if sim_mode == false and cmd_line == false then
  1426.             length = getInput("int","How long does each side need to be?")
  1427.             height = getInput("int","What height does it need to be?")
  1428.         elseif sim_mode == true or cmd_line == true then
  1429.             length = tempProgTable.param1
  1430.             height = tempProgTable.param2
  1431.         end
  1432.         tempProgTable.param1 = length
  1433.         tempProgTable.param2 = height
  1434.         progTable = {param1 = length, param2 = height}
  1435.         eightprism(length, height)
  1436.     end
  1437.     if returntohome then
  1438.         goHome() -- After all shape building has finished
  1439.     end
  1440.     writeOut("Done") -- Saves a few lines when put here rather than in each if statement
  1441. end
  1442.  
  1443. function WriteMenu()
  1444.     term.clear()
  1445.     term.setCursorPos(1, 1)
  1446.     writeOut("Shape Maker 1.5 by Keridos/Happydude/pokemane")
  1447.     if resupply then                    -- Any ideas to make this more compact/betterlooking (in terms of code)?
  1448.         writeOut("Resupply Mode Active")
  1449.     elseif (resupply and can_use_gps) then
  1450.         writeOut("Resupply and GPS Mode Active")
  1451.     elseif can_use_gps then
  1452.         writeOut("GPS Mode Active")
  1453.     else
  1454.         writeOut("")
  1455.     end
  1456.     if not cmd_line then
  1457.         writeOut("What should be built? [page 1/2]");
  1458.         writeOut("next for page 2")
  1459.         writeOut("+---------+-----------+-------+-------+")
  1460.         writeOut("| square  | rectangle | wall  | line  |")
  1461.         writeOut("| cylinder| platform  | stair | cuboid|")
  1462.         writeOut("| pyramid | 1/2-sphere| circle| next  |")
  1463.         writeOut("+---------+-----------+-------+-------+")
  1464.         writeOut("")
  1465.     end
  1466. end
  1467.  
  1468. function WriteMenu2()
  1469.     term.clear()
  1470.     term.setCursorPos(1, 1)
  1471.     writeOut("Shape Maker 1.5 by Keridos/Happydude/pokemane")
  1472.     if resupply then                    -- Any ideas to make this more compact/betterlooking (in terms of code)?
  1473.         writeOut("Resupply Mode Active")
  1474.     elseif (resupply and can_use_gps) then
  1475.         writeOut("Resupply and GPS Mode Active")
  1476.     elseif can_use_gps then
  1477.         writeOut("GPS Mode Active")
  1478.     else
  1479.         writeOut("")
  1480.     end
  1481.     writeOut("What should be built [page 2/2]?");
  1482.     writeOut("")
  1483.     writeOut("+---------+-----------+-------+-------+")
  1484.     writeOut("| hexagon | octagon   | help  |       |")
  1485.     writeOut("| 6-prism | 8-prism   | end   |       |")
  1486.     writeOut("| sphere  | credits   |       |       |")
  1487.     writeOut("+---------+-----------+-------+-------+")
  1488.     writeOut("")
  1489. end
  1490.  
  1491. function showHelp()
  1492.     writeOut("Usage: shape [shape-type [param1 param2 param3 ...]] [-c] [-h] [-z] [-r]")
  1493.     writeOut("-c: Activate cost only mode")
  1494.     writeOut("-h: Show this page")
  1495.     writeOut("-z: Set chain_next_shape to true, lets you chain together multiple shapes")
  1496.     io.read() -- Pause here
  1497.     writeOut("-r: Resume the last shape if there is a resume file")
  1498.     writeOut("shape-type can be any of the shapes in the menu")
  1499.     writeOut("After shape-type input all of the paramaters for the shape")
  1500.     io.read() -- Pause here, too
  1501. end
  1502.  
  1503. function showCredits()
  1504.     writeOut("Credits for the shape builder:")
  1505.     writeOut("Based on work by Michiel,Vliekkie, and Aeolun")
  1506.     writeOut("Sphere/dome code by pruby")
  1507.     writeOut("Additional improvements by Keridos,Happydude and pokemane")
  1508.     io.read() -- Pause here, too
  1509. end
  1510.  
  1511. function main()
  1512.     if wrapmodules()=="resupply" then
  1513.         linkToRSStation()
  1514.     end
  1515.     if checkCommandLine() then
  1516.         if needsHelp() then
  1517.             showHelp()
  1518.             return -- Close the program after help info is shown
  1519.         end
  1520.         setFlagsFromCommandLine()
  1521.         setTableFromCommandLine()
  1522.     end
  1523.     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
  1524.         if not continueQuery() then -- If the user doesn't want to continue
  1525.             ProgressFileDelete()
  1526.             setSimFlags(false) -- Just to be safe
  1527.             WriteMenu()
  1528.             choiceFunction()
  1529.         else    -- If the user wants to continue
  1530.             setSimFlags(true)
  1531.             choiceFunction()
  1532.         end
  1533.     else
  1534.         setSimFlags(false)
  1535.         WriteMenu()
  1536.         choiceFunction()
  1537.     end
  1538.     if (blocks ~= 0) and (fuel ~= 0) then -- Do not show on help or credits page or when selecting end
  1539.         writeOut("Blocks used: " .. blocks)
  1540.         writeOut("Fuel used: " .. fuel)
  1541.     end
  1542.     ProgressFileDelete() -- Removes file upon successful completion of a job, or completion of a previous job.
  1543.     progTable = {}
  1544.     tempProgTable = {}
  1545. end
  1546.  
  1547. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement