Advertisement
IMarvinTPA

Dome Builder Modified

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