Advertisement
Guest User

gatecontroller

a guest
Apr 8th, 2020
394
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.22 KB | None | 0 0
  1. function waitforinput()
  2.     while not (os.pullEvent("key")) do
  3.         -- wait
  4.     end
  5. end
  6.  
  7. function catastrophicError(text, solution)
  8.     if text == "Terminated" then
  9.         return --Terminating it isn't an error
  10.     end
  11.    
  12.     local w, h = term.getSize()
  13.     term.setBackgroundColor(colours.blue)
  14.     term.setTextColor(colours.white)
  15.  
  16.     term.clear()
  17.     local header = "ERROR"
  18.     local footer = "PRESS ANY KEY TO REBOOT"
  19.     local _solution = ""
  20.     if solution then
  21.         _solution = solution
  22.     else
  23.         _solution = "No Solution Available"
  24.     end
  25.  
  26.     term.setBackgroundColor(colours.white)
  27.     term.setTextColor(colours.blue)
  28.  
  29.     term.setCursorPos((w/2 - #header/2), 2)
  30.     term.write(header)
  31.  
  32.     term.setBackgroundColor(colours.blue)
  33.     term.setTextColor(colours.white)
  34.            
  35.     term.setCursorPos(1, 4)
  36.     print(text)
  37.  
  38.     term.setCursorPos(1, 8)
  39.     term.write("A possible solution is")
  40.  
  41.     term.setCursorPos(1, 9)
  42.     term.write("  * " .. _solution)
  43.  
  44.     term.setCursorPos((w/2 - #footer/2), h-1)
  45.     term.write(footer)
  46.  
  47.     waitforinput()
  48.     os.reboot()
  49. end
  50.  
  51. local stargate = peripheral.wrap("stargate_5")
  52. if not stargate then
  53.     catastrophicError("No Stargate Attached","Modify the program to match the situation")
  54. end
  55. --Copied from pastebin (i did write it manually at one point but it didn't work)
  56.  
  57. local button = { --Our main button table. Contains everything from button draw functions to the button information.
  58.   button_defaults = { --This is the metatable which we give set new buttons to. It provides color/size defaults.
  59.     __index = {
  60.       color_bg = colors.orange;
  61.       color_cl = colors.blue;
  62.       color_txt = colors.black;
  63.      
  64.       height = 3;
  65.       padding = 2;
  66.       isClicked = false;
  67.     };
  68.   };
  69.   mt = { --This is the main metatable of the button table. It changes the behavior of the table to allow for calling and adding new indexes.
  70.     __call = function(self) --This allows us to call the table as if it were a function.
  71.       for index, btn in pairs(self.buttons) do
  72.         if btn.enabled then
  73.           local color = btn.isClicked and btn.color_cl or btn.color_bg
  74.           term.setBackgroundColor(color)
  75.           term.setTextColor(btn.color_txt)
  76.           for yPos = btn.y, btn.bounds.y2 do
  77.             term.setCursorPos(btn.x, yPos)
  78.             term.write(string.rep(" ", btn.width))
  79.           end
  80.           local text = btn.isClicked and btn.clickText or btn.text
  81.           term.setCursorPos(btn.x + (btn.width/2 - #text/2), btn.y + (btn.height/2))
  82.           term.write(text)
  83.         end
  84.       end
  85.     end;
  86.    
  87.     __newindex = function(t, key, value) --This changes the behavior of the table upon adding a new button
  88.       assert(type(value)=="table", "Requires a table") --assert will check that a condition is true; if it is not, it will error with the provided text
  89.       assert(value.x, "Requires initial x")
  90.       assert(value.y, "Requires initial y")
  91.       assert(value.text, "Requires text value")
  92.       setmetatable(value, t.button_defaults) --Give our new button its defaults with the __index metamethod
  93.       value.width = #value.text + (value.padding * 2)
  94.       value.bounds = {
  95.         x1 = value.x; --I don't use the x1 or y1 vars from the bounds table due to the fact that it's shorter to simply type btn.x than btn.bounds.x, but they are equal to the same thing (obviously)
  96.         y1 = value.y;
  97.         x2 = value.x + value.width - 1; --In order to draw and detect clicks correctly, you need to subtract 1 from the width and height.
  98.         y2 = value.y + value.height - 1;
  99.       }
  100.       t.buttons[key]=value --In the video, I am aware that I used rawset. However, it is actually not necessary because we are not changing the button table directly, but rather the button.buttons table (which has no newindex metamethod)
  101.     end;
  102.   };
  103.  
  104.   checkClick = function(self, x,y) --This checks whether you have actually clicked on a table
  105.     for index, btn in pairs(self.buttons) do
  106.       if btn.enabled and x>=btn.x and x<=btn.bounds.x2 and y>=btn.y and y<=btn.bounds.y2 then
  107.         btn.isClicked = true --If we have actually clicked the button then set its click value to true
  108.         if btn.onClick then --And check if it has an onClick function
  109.           btn:onClick() --If so, then execute it and pass the button's table/info into it by using the colon operator
  110.         end
  111.         return index --Return the index of the button so we can unhighlight it
  112.       end
  113.     end
  114.   end;
  115.  
  116.   buttons = {}; --This is the table that we'll keep all the buttons in
  117.  
  118. }
  119. setmetatable(button, button.mt) --Set the metatable of button to button.mt
  120.  
  121. function inform(text)
  122.     term.setBackgroundColor(colours.black)
  123.     term.setTextColor(colours.white)
  124.     term.setCursorPos(1,1)
  125.     print(text)
  126.     waitforinput()
  127. end
  128.  
  129. --Gate Functions
  130. function toggleIris()
  131.     local irisState = stargate.irisState()
  132.     if irisState == "Closed" then
  133.         stargate.openIris()
  134.     elseif irisState == "Open" then
  135.         stargate.closeIris()
  136.     elseif irisState == "Offline" then
  137.         inform("No Iris installed.")
  138.     end
  139. end
  140.  
  141. function dialMenu()
  142.     local gateStatus = stargate.stargateState()
  143.     if gateStatus == "Dialling" then
  144.         inform("Currently Dialling Already")
  145.         return
  146.     elseif gateStatus == "Opening" or gateStatus == "Connected" or gateStatus == "Closing" then
  147.         inform("Gate is Busy.")
  148.         return
  149.     end
  150.    
  151.     term.setBackgroundColor(colours.green)
  152.     term.clear()
  153.     term.setCursorPos(1,1)
  154.     term.write("Enter Address:")
  155.     term.setCursorPos(1,2)
  156.     local address = read()
  157.     term.setCursorPos(1,3)
  158.     local energy = stargate.energyToDial(address)
  159.     local curEnergy = stargate.energyAvailable()
  160.    
  161.     if not energy then
  162.         inform(address .. " Is not an address!")
  163.         return
  164.     end
  165.    
  166.     term.write("It will take "..tostring(energy).." Energy.")
  167.    
  168.     energy = stargate.energyToDial(address)
  169.    
  170.     if energy > curEnergy then
  171.         term.setCursorPos(1,4)
  172.         term.write("Not enough energy.")
  173.         term.setCursorPos(1,5)
  174.         term.write("Press any key to continue.")
  175.         waitforinput()
  176.         return
  177.     end
  178.    
  179.     term.setCursorPos(1,4)
  180.     term.write("Are you sure?")
  181.     term.setCursorPos(1,5)
  182.     term.write("TODO: CHOICE (sorry)Uh meow")
  183.     term.setCursorPos(1,6)
  184.     term.write("Attempting to dial "..address)
  185.    
  186.     ok, err = pcall(stargate.dial,address)
  187.    
  188.     if not ok then
  189.         term.setCursorPos(1,7)
  190.         term.write("Gate Failed. Reason:")
  191.         term.setCursorPos(1,8)
  192.         term.write(err)
  193.         term.setCursorPos(1,9)
  194.     else
  195.         term.setCursorPos(1,7)
  196.         term.write("Happy Travels")
  197.     end
  198.    
  199.     term.setCursorPos(1,10)
  200.     term.write("Press Any key To continue.")
  201.    
  202.     waitforinput()
  203. end
  204.  
  205. function closeGate()
  206.     local stargateStatus, stargateEngaged, wormholeDirection = stargate.stargateState()
  207.     if stargateStatus == "Idle" or not stargateStatus == "Connected" then
  208.         inform("Cannot close gate at this time")
  209.         return
  210.     end
  211.     if wormholeDirecton == "Outgoing" then
  212.         inform("Cannot close incoming wormhole!")
  213.         return
  214.     end
  215.    
  216.     stargate.disconnect()
  217. end
  218.  
  219. --GUI stuff
  220. button[1] = {
  221.   x = 1;
  222.   y = 1;
  223.   text = "Toggle Iris";
  224.   enabled = true;
  225.   clickText = text;
  226.   onClick = toggleIris;
  227. }
  228.  
  229. button[2] = {
  230.   x = 1;
  231.   y = 5;
  232.   text = "Dial Address";
  233.   clickText = text;
  234.   enabled = true;
  235.   onClick = dialMenu;
  236. }
  237. button[3] = {
  238.   x = 1;
  239.   y = 9;
  240.   text = "Close Gate";
  241.   clickText = text;
  242.   enabled = true;
  243.   onClick = closeGate;
  244. }
  245.  
  246. local timer = { --This will keep track of clicked buttons/the timers associated with them
  247.   index = false;
  248.   timer = false;
  249. }
  250.  
  251. local termSize = {term.getSize()}
  252.  
  253. function main()
  254.   while true do
  255.     term.setBackgroundColor(colours.grey)
  256.     term.clear()
  257.  
  258.     button() --Always draw the button first
  259.    
  260.     term.setCursorPos(1,termSize[2]-1)
  261.     term.setBackgroundColor(colours.blue)
  262.     term.write("Gate Energy " .. tostring(stargate.energyAvailable()))
  263.     term.setCursorPos(1,termSize[2])
  264.     term.write("Gate Address " .. stargate.localAddress() .. " Connected to ".. stargate.remoteAddress())
  265.    
  266.     local e = {os.pullEvent()} --Then pull our events
  267.     if e[1] == "mouse_click" then
  268.       local index = button:checkClick(e[3], e[4]) --Check the click: make sure to pass the button table into the checkClick function
  269.       if index then
  270.         timer.index =  index--The index of the button that is clicked
  271.         timer.timer = os.startTimer(1)
  272.       end
  273.     elseif e[1] == "timer" and e[2] == timer.timer then --If we get a timer event and the ID is equal to the timer.timer var then
  274.       button.buttons[timer.index].isClicked = false --Deselect the button
  275.       timer = {} --This is actually fairly memory inneficient, but for such a small program it doesn't really matter. Rather than do this though, you should probably just manually set the values of timer.index/timer.timer to false
  276.     elseif e[1] == "sgMessageRecieved" then
  277.         inform(e[2])
  278.     elseif e[1] == "sgStargateStateChange" then
  279.     end
  280.    
  281.   end
  282. end
  283.  
  284. --Error Handling
  285. xpcall(main, catastrophicError)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement