Advertisement
Lyqyd

Generalized Setup

Jun 7th, 2014
479
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2. The MIT License (MIT)
  3.  
  4. Copyright (c) 2014 Lyqyd
  5.  
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12.  
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15.  
  16. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. THE SOFTWARE.
  23. --]]
  24.  
  25. if not location then if shell.resolveProgram("location") then os.loadAPI(shell.resolveProgram("location")) elseif fs.exists("usr/apis/location") then os.loadAPI("usr/apis/location") else error("Could not load location API!") end end
  26.  
  27. local projectOffset = 1
  28. local projectCursor = 1
  29. local project, loc, buildLoc
  30. local display, handler
  31. local beginProject = false
  32. local headingNames = {"West", "North", "East", "South"}
  33. local posIsGPS = false
  34. local editingTable, editingKey, editingCursorPos
  35.  
  36. local function constructEnv()
  37.     local env = {requirements = project.requirements, shell = shell}
  38.     setmetatable(env, {__index = _G})
  39.     if env.requirements.locations then
  40.         env.requirements.locations.start = loc
  41.         env.requirements.locations.setup = buildLoc
  42.     end
  43.     return env
  44. end
  45.  
  46. local function resetState()
  47.     project = nil
  48.     projectOffset = 1
  49.     projectCursor = 1
  50.     buildLoc = nil
  51.     if not posIsGPS then loc = nil end
  52.     beginProject = false
  53.     editingTable, editingKey, editingCursorPos = nil, nil, nil
  54. end
  55.  
  56. local projects = {}
  57. local projectDir = ""
  58.  
  59. if fs.exists("/etc/projects") and fs.isDir("/etc/projects") then
  60.     projectDir = "/etc/projects"
  61. elseif fs.getDir and fs.exists(fs.combine(fs.getDir(shell.getRunningProgram()), "projects")) and fs.isDir(fs.combine(fs.getDir(shell.getRunningProgram()), "projects")) then
  62.     projectDir = fs.combine(fs.getDir(shell.getRunningProgram()), "projects")
  63. elseif fs.exists("/projects") and fs.isDir("/projects") then
  64.     projectDir = "/projects"
  65. end
  66.  
  67. if projectDir then
  68.     for _, name in pairs(fs.list(projectDir)) do
  69.         local file = fs.combine(projectDir, name)
  70.         local usefulEnv = {shell = shell}
  71.         setmetatable(usefulEnv, {__index = _G})
  72.         local env = {}
  73.         setmetatable(env, {__index = usefulEnv})
  74.         local fn, err = loadfile(file)
  75.         if fn then
  76.             setfenv(fn, env)
  77.             fn()
  78.             --copy into project table
  79.             projects[env.name] = {}
  80.             for k, v in pairs(env) do
  81.                 projects[env.name][k] = v
  82.             end
  83.         end
  84.     end
  85. else
  86.     print("Could not find project folder!")
  87.     return
  88. end
  89.  
  90. local sortedProjects = {}
  91. for name in pairs(projects) do
  92.     table.insert(sortedProjects, name)
  93. end
  94. table.sort(sortedProjects)
  95.  
  96. local function printCenter(text)
  97.     text = tostring(text)
  98.     local x, y = term.getSize()
  99.     local xCur, yCur = term.getCursorPos()
  100.     term.setCursorPos((x - #text) / 2 + 1, yCur)
  101.     term.write(text)
  102. end
  103.  
  104. local function isSlotReady(slot)
  105.     if project and project.requirements.slots then
  106.         local slotReq = project.requirements.slots[slot]
  107.         if slotReq.readyFunction then
  108.             return slotReq.readyFunction()
  109.         elseif slotReq.exactCount then
  110.             return slotReq.minCount == slotReq.maxCount and slotReq.minCount == turtle.getItemCount(slot)
  111.         else
  112.             return turtle.getItemCount(slot) >= slotReq.minCount
  113.         end
  114.     else
  115.         return false
  116.     end
  117. end
  118.  
  119. local function areAllSlotsReady()
  120.     if project and project.requirements.slots then
  121.         for i = 1, #project.requirements.slots do
  122.             if not isSlotReady(i) then return false end
  123.         end
  124.         return true
  125.     else
  126.         return false
  127.     end
  128. end
  129.  
  130. local function areLocationsReady()
  131.     if project and project.requirements.locations then
  132.         if loc and loc.x and loc.y and loc.z and loc.y > 0 and buildLoc and buildLoc.x and buildLoc.y and buildLoc.z and buildLoc.y > 0 then
  133.             return true
  134.         else
  135.             return false
  136.         end
  137.     else
  138.         return true
  139.     end
  140. end
  141.  
  142. local function isFuelSufficient()
  143.     if project and project.requirements.fuel then
  144.         local fuelCost = project.requirements.fuel
  145.         if type(project.requirements.fuel) == "function" then
  146.             local env = constructEnv()
  147.             setfenv(project.requirements.fuel, env)
  148.             fuelCost = project.requirements.fuel()
  149.         end
  150.         local otherRequirements = true
  151.         if project and project.requirements.other and type(project.requirements.other) == "function" then
  152.             otherRequirements = project.requirements.other()
  153.         end
  154.         return turtle.getFuelLevel() >= fuelCost and otherRequirements
  155.     else
  156.         return false
  157.     end
  158. end
  159.  
  160. local function isReady()
  161.     return project and areAllSlotsReady() and areLocationsReady() and isFuelSufficient()
  162. end
  163.  
  164. local displayProjects, handleProjects, displayRequirements, handleRequirements, displaySlots, handleSlots, displayLocations, handleLocations, displayLocationOptions, handleLocationOptions, displayFueling, handleFueling
  165.  
  166. function displayProjects()
  167.     local x, y = term.getSize()
  168.     local function projectLine(index)
  169.         if term.isColor() then
  170.             term.setBackgroundColor(index % 2 == 0 and colors.white or colors.lightGray)
  171.             term.setTextColor(colors.black)
  172.         else
  173.             if index == projectCursor then
  174.                 term.setBackgroundColor(colors.white)
  175.                 term.setTextColor(colors.black)
  176.             else
  177.                 term.setBackgroundColor(colors.black)
  178.                 term.setTextColor(colors.white)
  179.             end
  180.         end
  181.         term.clearLine()
  182.         local x, y = term.getCursorPos()
  183.         term.setCursorPos(2, y)
  184.         term.write(projects[sortedProjects[index]].name)
  185.     end
  186.     term.setBackgroundColor(term.isColor() and colors.gray or colors.black)
  187.     term.setTextColor(colors.white)
  188.     term.clear()
  189.     term.setCursorPos(1, 1)
  190.     printCenter("Project List")
  191.     for i = 1, math.min(#sortedProjects, y - 2) do
  192.         term.setCursorPos(1, i + 2)
  193.         projectLine(projectOffset + i - 1)
  194.     end
  195. end
  196.  
  197. function handleProjects(event)
  198.     local x, y = term.getSize()
  199.     if event[1] == "mouse_click" then
  200.         if event[4] >= 3 and event[4] <= y then
  201.             --clicked somewhere in the places list
  202.             if event[3] == x then
  203.                 --clicked the scroll bar.
  204.                 if event[4] == 3 then
  205.                     --up
  206.                     if projectOffset > 1 then
  207.                         projectOffset = projectOffset - 1
  208.                     end
  209.                 elseif event[4] == y then
  210.                     if projectOffset + y - 3 < #sortedProjects then
  211.                         projectOffset = projectOffset + 1
  212.                     end
  213.                 end
  214.             else
  215.                 --clicked on a place!
  216.                 local index = projectOffset + event[4] - 3
  217.                 if index <= #sortedProjects then
  218.                     project = projects[sortedProjects[index]]
  219.                     display = displayRequirements
  220.                     handler = handleRequirements
  221.                     --we have a project selected, use projects[sortedProjects[index]] to access.
  222.                 end        
  223.             end
  224.         end
  225.     elseif event[1] == "key" and not term.isColor() then
  226.         if event[2] == 200 then
  227.             --up
  228.             projectCursor = math.max(projectCursor - 1, 1)
  229.         elseif event[2] == 208 then
  230.             --down
  231.             projectCursor = math.min(projectCursor + 1, #sortedProjects)
  232.         elseif event[2] == 28 then
  233.             --enter, selects a project
  234.             project = projects[sortedProjects[projectCursor]]
  235.             display = displayRequirements
  236.             handler = handleRequirements
  237.         end
  238.         --attempt to keep cursor on screen
  239.         if projectCursor < projectOffset then
  240.             projectOffset = projectCursor
  241.         elseif projectOffset + y - 2 < projectCursor then
  242.             projectOffset = projectCursor - y + 2
  243.         end
  244.     end
  245. end
  246.  
  247. local function drawRequirementsHeader()
  248.     local function setColors(bool)
  249.         if term.isColor() then
  250.             term.setBackgroundColor(bool and colors.green or colors.red)
  251.             term.setTextColor(colors.white)
  252.         else
  253.             term.setBackgroundColor(bool and colors.black or colors.white)
  254.             term.setTextColor(bool and colors.white or colors.black)
  255.         end
  256.     end
  257.     local x, y = term.getSize()
  258.     term.setCursorPos(1, 1)
  259.     term.setBackgroundColor(term.isColor() and colors.gray or colors.black)
  260.     term.setTextColor(colors.white)
  261.     term.clear()
  262.     printCenter(project.name.." - Requirements")
  263.     do
  264.         if project.requirements.slots then
  265.             term.setCursorPos(4, 3)
  266.             setColors(areAllSlotsReady())
  267.             term.write(" SLOTS ")
  268.         end
  269.         if project.requirements.locations then
  270.             term.setCursorPos(14, 3)
  271.             setColors(areLocationsReady())
  272.             term.write(" LOCATIONS ")
  273.         end
  274.         if project.requirements.fuel then
  275.             term.setCursorPos(27, 3)
  276.             setColors(isFuelSufficient())
  277.             term.write(" FUEL/ETC ")
  278.         end
  279.     end
  280. end
  281.  
  282. local function handleRequirementsHeader(event)
  283.     if event[1] == "mouse_click" and event[2] == 1 then
  284.         if event[4] == 3 then
  285.             if event[3] >= 4 and event[3] <= 10 then
  286.                 --clicked Slots
  287.                 display = displaySlots
  288.                 handler = handleSlots
  289.             elseif event[3] >= 14 and event[3] <= 24 then
  290.                 --clicked Locations
  291.                 display = displayLocations
  292.                 handler = handleLocations
  293.             elseif event[3] >= 28 and event[3] <= 36 then
  294.                 --clicked Fueling
  295.                 display = displayFueling
  296.                 handler = handleFueling
  297.             end
  298.         end
  299.     elseif event[1] == "char" then
  300.         if string.lower(event[2]) == "s" and project.requirements.slots then
  301.             --slots
  302.             display = displaySlots
  303.             handler = handleSlots
  304.         elseif string.lower(event[2]) == "l" and project.requirements.locations then
  305.             --locations
  306.             display = displayLocations
  307.             handler = handleLocations
  308.         elseif string.lower(event[2]) == "f" and project.requirements.fuel then
  309.             --fueling
  310.             display = displayFueling
  311.             handler = handleFueling
  312.         end
  313.     end
  314. end
  315.  
  316. function displayRequirements()
  317.     drawRequirementsHeader()
  318. end
  319.  
  320. function handleRequirements(event)
  321.     handleRequirementsHeader(event)
  322. end
  323.  
  324. function displaySlots()
  325.     drawRequirementsHeader()
  326.     local function setColors(bool)
  327.         if term.isColor() then
  328.             term.setBackgroundColor(colors.gray)
  329.             term.setTextColor(bool and colors.lime or colors.red)
  330.         else
  331.             term.setBackgroundColor(bool and colors.black or colors.white)
  332.             term.setTextColor(bool and colors.white or colors.black)
  333.         end
  334.     end
  335.     local x, y = term.getSize()
  336.     term.setCursorPos(1, 1)
  337.     term.setBackgroundColor(term.isColor() and colors.gray or colors.black)
  338.     term.setTextColor(colors.white)
  339.     term.clearLine()
  340.     printCenter(project.name.." - Slots")
  341.     do
  342.         for i = 1, #project.requirements.slots do
  343.             local slot = project.requirements.slots[i]
  344.             if i > 8 then
  345.                 term.setCursorPos(math.ceil(x / 2), i - 4)
  346.             else
  347.                 term.setCursorPos(2, i + 4)
  348.             end
  349.             term.setBackgroundColor(term.isColor() and colors.gray or colors.black)
  350.             term.setTextColor(colors.white)
  351.             term.write(i..": ")
  352.             setColors(isSlotReady(i))
  353.             if slot.minCount == slot.maxCount then
  354.                 term.write(tostring(slot.minCount).." "..slot.name)
  355.             else
  356.                 term.write(tostring(slot.minCount).."-"..tostring(slot.maxCount).." "..slot.name)
  357.             end
  358.         end
  359.     end
  360. end
  361.  
  362. function handleSlots(event)
  363.     if event[1] == "mouse_click" then
  364.         if event[4] <= 4 then
  365.             return handleRequirementsHeader(event)
  366.         end
  367.     elseif event[1] == "char" then
  368.         return handleRequirementsHeader(event)
  369.     end
  370. end
  371.  
  372. function displayLocations()
  373.     drawRequirementsHeader()
  374.     local x, y = term.getSize()
  375.     local column = math.ceil(x / 2)
  376.     term.setCursorPos(1, 1)
  377.     term.setBackgroundColor(term.isColor() and colors.gray or colors.black)
  378.     term.setTextColor(colors.white)
  379.     term.clearLine()
  380.     printCenter(project.name.." - Locations")
  381.     do
  382.         term.setCursorPos(2, 5)
  383.         term.write("Current Position")
  384.         term.setCursorPos(2, 6)
  385.         term.write("X: ")
  386.         if loc and loc.x then
  387.             term.write(tostring(loc.x))
  388.         end
  389.         term.setCursorPos(2, 7)
  390.         term.write("Y: ")
  391.         if loc and loc.y then
  392.             term.write(tostring(loc.y))
  393.         end
  394.         term.setCursorPos(2, 8)
  395.         term.write("Z: ")
  396.         if loc and loc.z then
  397.             term.write(tostring(loc.z))
  398.         end
  399.         term.setCursorPos(2, 9)
  400.         term.write("Facing: ")
  401.         if loc and loc.h and headingNames[loc.h] then
  402.             term.write(headingNames[loc.h])
  403.         end
  404.     end
  405.     do
  406.         term.setCursorPos(column, 5)
  407.         term.write("Build Position")
  408.         term.setCursorPos(column, 6)
  409.         term.write("X: ")
  410.         if buildLoc and buildLoc.x then
  411.             term.write(tostring(buildLoc.x))
  412.         end
  413.         term.setCursorPos(column, 7)
  414.         term.write("Y: ")
  415.         if buildLoc and buildLoc.y then
  416.             term.write(tostring(buildLoc.y))
  417.         end
  418.         term.setCursorPos(column, 8)
  419.         term.write("Z: ")
  420.         if buildLoc and buildLoc.z then
  421.             term.write(tostring(buildLoc.z))
  422.         end
  423.         term.setCursorPos(column, 9)
  424.         term.write("Facing: ")
  425.         if buildLoc and buildLoc.h and headingNames[buildLoc.h] then
  426.             term.write(headingNames[buildLoc.h])
  427.         end
  428.         if project.requirements.locations and #project.requirements.locations > 0 then
  429.             term.setCursorPos((x - column - 9) / 2 + column, 11)
  430.             term.write("(Options)")
  431.         end
  432.     end
  433.     do
  434.         if editingTable and editingKey and editingCursorPos then
  435.             local columns = {[loc] = 2, [buildLoc] = column}
  436.             local lines = {x = 6, y = 7, z = 8}
  437.             term.setCursorPos(columns[editingTable] + 3, lines[editingKey])
  438.             term.write(tostring(editingTable[editingKey]))
  439.             term.setCursorPos(columns[editingTable] + 2 + editingCursorPos, lines[editingKey])
  440.             term.setCursorBlink(true)
  441.         else
  442.             term.setCursorBlink(false)
  443.         end
  444.     end
  445. end
  446.  
  447. local function numericRead(event)
  448.     local function set(str)
  449.         if #str == 0 then str = "0" end
  450.         if tonumber(str) then
  451.             editingTable[editingKey] = tonumber(str)
  452.         end
  453.     end
  454.  
  455.     local str = tostring(editingTable[editingKey])
  456.     if event[1] == "char" then
  457.         if event[2] == "-" then
  458.             editingTable[editingKey] = editingTable[editingKey] * -1
  459.         elseif tonumber(event[2]) ~= nil then
  460.             if str == "0" then
  461.                 str = event[2]
  462.                 set(str)
  463.                 editingCursorPos = 2
  464.             else
  465.                 local length = #str
  466.                 str = string.sub(str, 1, editingCursorPos - 1)..event[2]..string.sub(str, editingCursorPos)
  467.                 set(str)
  468.                 if #str > length then
  469.                     editingCursorPos = math.min(editingCursorPos + 1, #str + 1)
  470.                 end
  471.             end
  472.         else
  473.             return handleRequirementsHeader(event)
  474.         end
  475.     elseif event[1] == "key" then
  476.         if event[2] == 28 then
  477.             editingTable = nil
  478.             editingKey = nil
  479.             editingCursorPos = nil
  480.         elseif event[2] == 14 then
  481.             --backspace
  482.             local length = #str
  483.             str = string.sub(str, 1, editingCursorPos - 2)..string.sub(str, editingCursorPos)
  484.             if length > #str then
  485.                 editingCursorPos = math.max(editingCursorPos - 1, 1)
  486.             end
  487.             set(str)
  488.         elseif event[2] == 211 then
  489.             --delete
  490.             str = string.sub(str, 1, editingCursorPos - 1)..string.sub(str, editingCursorPos + 1)
  491.             set(str)
  492.         elseif event[2] == 203 then
  493.             --left
  494.             editingCursorPos = math.max(editingCursorPos - 1, 1)
  495.         elseif event[2] == 205 then
  496.             --right
  497.             editingCursorPos = math.min(editingCursorPos + 1, #str + 1)
  498.         elseif event[2] == 199 then
  499.             --home
  500.             editingCursorPos = 1
  501.         elseif event[2] == 207 then
  502.             --end
  503.             editingCursorPos = #str + 1
  504.         end
  505.     end
  506. end
  507.  
  508. function handleLocations(event)
  509.     local x, y = term.getSize()
  510.     local column = math.ceil(x / 2)
  511.     if event[1] == "mouse_click" then
  512.         if event[4] <= 4 then
  513.             handleRequirementsHeader(event)
  514.             if display ~= displayLocations then
  515.                 term.setCursorBlink(false)
  516.                 editingTable, editingKey, editingCursorPos = nil, nil, nil
  517.                 return
  518.             end
  519.         elseif event[4] >= 6 and event[4] <= 8 then
  520.             --clicked on one of the six xyz position entries.
  521.             if event[3] >= 2 and event[3] <= column - 2 then
  522.                 --if GPS position, cannot edit starting positions.
  523.                 if posIsGPS then return end
  524.                 editingTable = loc
  525.             elseif event[3] >= column and event[3] <= x - 1 then
  526.                 if not buildLoc then buildLoc = location.new() end
  527.                 editingTable = buildLoc
  528.             end
  529.             local keyLookup = {[6] = "x", [7] = "y", [8] = "z"}
  530.             editingKey = keyLookup[event[4]]
  531.             editingCursorPos = string.len(tostring(editingTable[editingKey])) + 1
  532.         elseif event[4] == 9 then
  533.             if event[3] >= 2 and event[3] <= column - 2 then
  534.                 --adjust start position facing unless position is GPS-based
  535.                 if posIsGPS then return end
  536.                 loc.h = loc.h + 1
  537.                 if loc.h == 5 then loc.h = 1 end
  538.             elseif event[3] >= column and event[3] <= x - 1 then
  539.                 --adjust build position facing
  540.                 buildLoc.h = buildLoc.h + 1
  541.                 if buildLoc.h == 5 then buildLoc.h = 1 end
  542.             end
  543.         elseif event[4] == 11 then
  544.             local optionsStart = (x - column - 9) / 2 + column
  545.             if event[3] >= optionsStart and event[3] <= optionsStart + 8 and #project.requirements.locations > 0 then
  546.                 --clicked Options
  547.                 term.setCursorBlink(false)
  548.                 editingTable, editingKey, editingCursorPos = nil, nil, nil
  549.                 display = displayLocationOptions
  550.                 handler = handleLocationOptions
  551.             end
  552.         end
  553.     elseif event[1] == "char" or event[1] == "key" then
  554.         if event[1] == "key" and event[2] == 15 then
  555.             --they hit tab
  556.             if editingTable then
  557.                 if editingKey ~= "z" then
  558.                     editingKey = string.char(string.byte(editingKey) + 1)
  559.                 else
  560.                     editingKey = "x"
  561.                     if posIsGPS then
  562.                         editingTable = buildLoc
  563.                     else
  564.                         editingTable = editingTable == loc and buildLoc or loc
  565.                     end
  566.                 end
  567.             else
  568.                 if posIsGPS then
  569.                     editingTable = buildLoc
  570.                 else
  571.                     editingTable = loc
  572.                 end
  573.                 editingKey = "x"
  574.                 editingCursorPos = string.len(tostring(editingTable[editingKey])) + 1
  575.             end
  576.         elseif editingTable and editingKey and editingCursorPos then
  577.             numericRead(event)
  578.         elseif event[1] == "char" then
  579.             if event[2] == "h" then
  580.                 --loc facing
  581.                 if posIsGPS then return end
  582.                 loc.h = loc.h + 1
  583.                 if loc.h == 5 then loc.h = 1 end
  584.             elseif event[2] == "H" then
  585.                 --buildLoc facing
  586.                 buildLoc.h = buildLoc.h + 1
  587.                 if buildLoc.h == 5 then buildLoc.h = 1 end
  588.             elseif string.lower(event[2]) == "o" and #project.requirements.locations > 0 then
  589.                 --options
  590.                 term.setCursorBlink(false)
  591.                 editingTable, editingKey, editingCursorPos = nil, nil, nil
  592.                 display = displayLocationOptions
  593.                 handler = handleLocationOptions
  594.             else
  595.                 return handleRequirementsHeader(event)
  596.             end
  597.         end
  598.     end
  599. end
  600.  
  601. function displayLocationOptions()
  602.     drawRequirementsHeader()
  603.     local x, y = term.getSize()
  604.     local column = math.ceil(x / 2)
  605.     term.setCursorPos(1, 1)
  606.     term.setBackgroundColor(term.isColor() and colors.gray or colors.black)
  607.     term.setTextColor(colors.white)
  608.     term.clearLine()
  609.     printCenter(project.name.." - Locations")
  610.     do
  611.         term.setCursorPos(2, 5)
  612.         if project.requirements.locations.name then
  613.             term.write(project.requirements.locations.name)
  614.         else
  615.             term.write("Location Options")
  616.         end
  617.         for i, locData in ipairs(project.requirements.locations) do
  618.             term.setCursorPos(2, i + 5)
  619.             if not term.isColor() then
  620.                 term.write(tostring(i)..": ")
  621.             end
  622.             term.write(locData.name)
  623.             term.setCursorPos(column, i + 5)
  624.             if type(locData.location) == "function" then
  625.                 local env = constructEnv()
  626.                 setfenv(locData.location, env)
  627.                 term.write(tostring(locData.location()))
  628.             else
  629.                 term.write(tostring(locData.location))
  630.             end
  631.         end
  632.     end
  633. end
  634.  
  635. function handleLocationOptions(event)
  636.     if event[1] == "mouse_click" then
  637.         if event[4] <= 4 then
  638.             return handleRequirementsHeader(event)
  639.         elseif event[4] >= 6 and event[4] <= #project.requirements.locations + 5 then
  640.             if type(project.requirements.locations[event[4] - 5].location) == "function" then
  641.                 buildLoc = project.requirements.locations[event[4] - 5].location()
  642.             else
  643.                 buildLoc = project.requirements.locations[event[4] - 5].location
  644.             end
  645.             display = displayLocations
  646.             handler = handleLocations
  647.         end
  648.     elseif event[1] == "char" then
  649.         if tonumber(event[2]) then
  650.             if type(project.requirements.locations[tonumber(event[2])].location) == "function" then
  651.                 buildLoc = project.requirements.locations[tonumber(event[2])].location()
  652.             else
  653.                 buildLoc = project.requirements.locations[tonumber(event[2])].location
  654.             end
  655.             display = displayLocations
  656.             handler = handleLocations
  657.         else
  658.             return handleRequirementsHeader(event)
  659.         end
  660.     end
  661. end
  662.  
  663. function displayFueling()
  664.     drawRequirementsHeader()
  665.     local function setColors(bool)
  666.         if term.isColor() then
  667.             term.setBackgroundColor(colors.gray)
  668.             term.setTextColor(bool and colors.lime or colors.red)
  669.         else
  670.             term.setBackgroundColor(bool and colors.black or colors.white)
  671.             term.setTextColor(bool and colors.white or colors.black)
  672.         end
  673.     end
  674.     local x, y = term.getSize()
  675.     local column = math.ceil(x / 2)
  676.     term.setCursorPos(1, 1)
  677.     term.setBackgroundColor(term.isColor() and colors.gray or colors.black)
  678.     term.setTextColor(colors.white)
  679.     term.clearLine()
  680.     printCenter(project.name.." - Fueling")
  681.     do
  682.         local fuelCost = project.requirements.fuel
  683.         if type(project.requirements.fuel) == "function" then
  684.             local env = constructEnv()
  685.             setfenv(project.requirements.fuel, env)
  686.             fuelCost = project.requirements.fuel()
  687.         end
  688.         local fuel = turtle.getFuelLevel()
  689.         term.setCursorPos(2, 5)
  690.         term.write("Fuel ")
  691.         if #project.requirements.slots < 16 then
  692.             if term.isColor() then
  693.                 term.setTextColor(colors.lightGray)
  694.                 term.write("(Refuel)")
  695.             else
  696.                 term.write("(")
  697.                 term.setBackgroundColor(colors.white)
  698.                 term.setTextColor(colors.black)
  699.                 term.write("R")
  700.                 term.setBackgroundColor(colors.black)
  701.                 term.setTextColor(colors.white)
  702.                 term.write("efuel)")
  703.             end
  704.         end
  705.         term.setTextColor(colors.white)
  706.         term.setCursorPos(2, 6)
  707.         term.write("Available: ")
  708.         setColors(fuel >= fuelCost)
  709.         term.write(tostring(fuel))
  710.         term.setBackgroundColor(term.isColor() and colors.gray or colors.black)
  711.         term.setTextColor(colors.white)
  712.         term.setCursorPos(2, 7)
  713.         term.write("Required: "..fuelCost)
  714.     end
  715.     do
  716.         if project.requirements.other and type(project.requirements.other) then
  717.             local preReqs = {project.requirements.other()}
  718.             if preReqs[1] == false then
  719.                 term.setCursorPos(column, 5)
  720.                 term.setTextColor(colors.white)
  721.                 term.write("Unmet Requirements:")
  722.                 for i = 2, #preReqs do
  723.                     term.setCursorPos(column, i + 4)
  724.                     term.write(preReqs[i])
  725.                 end
  726.             end
  727.         end
  728.     end
  729. end
  730.  
  731. function handleFueling(event)
  732.     if event[1] == "mouse_click" then
  733.         if event[4] <= 4 then
  734.             return handleRequirementsHeader(event)
  735.         elseif event[4] == 5 and event[3] >= 10 and event[3] <= 17 then
  736.             --clicked Refuel
  737.             for i = #project.requirements.slots + 1, 16 do
  738.                 turtle.select(i)
  739.                 turtle.refuel(64)
  740.             end
  741.         end
  742.     elseif event[1] == "char" then
  743.         if event[2] == "r" then
  744.             for i = #project.requirements.slots + 1, 16 do
  745.                 turtle.select(i)
  746.                 turtle.refuel(64)
  747.             end
  748.         else
  749.             return handleRequirementsHeader(event)
  750.         end
  751.     end
  752. end
  753.  
  754. do
  755.     local gpsVec = vector.new(gps.locate(0.5))
  756.     if gpsVec.y > 0 then
  757.         --if gps is already available, use those coordinates.
  758.         loc = location.new(gpsVec.x, gpsVec.y, gpsVec.z, 0)
  759.         if turtle.forward() then
  760.             local secLoc = vector.new(gps.locate())
  761.             local head = secLoc - gpsVec
  762.             loc.h = location.getOrientation(head.x, head.z)
  763.             if not turtle.back() then
  764.                 loc.x, loc.y, loc.z = secLoc.x, secLoc.y, secLoc.z
  765.             end
  766.             --set starting position to be unmodifiable.
  767.             posIsGPS = true
  768.         end
  769.     else
  770.         loc = location.new(0, 0, 0, 0)
  771.         buildLoc = location.new(0, 0, 0, 0)
  772.     end
  773. end
  774.  
  775. display = displayProjects
  776. handler = handleProjects
  777.  
  778. while not beginProject do
  779.     display()
  780.     if isReady() then
  781.         local xCur, yCur = term.getCursorPos()
  782.         local x, y = term.getSize()
  783.         term.setCursorPos(1, y)
  784.         term.setBackgroundColor(term.isColor() and colors.green or colors.black)
  785.         term.setTextColor(colors.white)
  786.         printCenter(" GO ")
  787.         term.setBackgroundColor(term.isColor() and colors.gray or colors.black)
  788.         term.setCursorPos(xCur, yCur)
  789.     end
  790.     local event = {os.pullEvent()}
  791.     if event[1] == "mouse_click" then
  792.         local x, y = term.getSize()
  793.         if event[4] == y and isReady() then
  794.             local start = (x - 4) / 2 + 1
  795.             if event[3] >= start and event[3] <= start + 3 then
  796.                 beginProject = true
  797.             else
  798.                 handler(event)
  799.             end
  800.         elseif event[4] == 1 then
  801.             display = displayProjects
  802.             handler = handleProjects
  803.             resetState()
  804.         else
  805.             handler(event)
  806.         end
  807.     elseif event[1] == "char" then
  808.         if event[2] == "q" then
  809.             break
  810.         elseif event[2] == "p" then
  811.             --reset project
  812.             display = displayProjects
  813.             handler = handleProjects
  814.             resetState()
  815.         elseif event[2] == "g" and isReady() then
  816.             beginProject = true
  817.         else
  818.             handler(event)
  819.         end
  820.     else
  821.         handler(event)
  822.     end
  823. end
  824.  
  825. if beginProject then
  826.     setfenv(project.instructions, constructEnv())
  827.     project.instructions()
  828. else
  829.     term.setBackgroundColor(colors.black)
  830.     term.setTextColor(colors.white)
  831.     term.clear()
  832.     term.setCursorPos(1,1)
  833. end
Advertisement
RAW Paste Data Copied
Advertisement