Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function waitforinput()
- while not (os.pullEvent("key")) do
- -- wait
- end
- end
- function catastrophicError(text, solution)
- if text == "Terminated" then
- return --Terminating it isn't an error
- end
- local w, h = term.getSize()
- term.setBackgroundColor(colours.blue)
- term.setTextColor(colours.white)
- term.clear()
- local header = "ERROR"
- local footer = "PRESS ANY KEY TO REBOOT"
- local _solution = ""
- if solution then
- _solution = solution
- else
- _solution = "No Solution Available"
- end
- term.setBackgroundColor(colours.white)
- term.setTextColor(colours.blue)
- term.setCursorPos((w/2 - #header/2), 2)
- term.write(header)
- term.setBackgroundColor(colours.blue)
- term.setTextColor(colours.white)
- term.setCursorPos(1, 4)
- print(text)
- term.setCursorPos(1, 8)
- term.write("A possible solution is")
- term.setCursorPos(1, 9)
- term.write(" * " .. _solution)
- term.setCursorPos((w/2 - #footer/2), h-1)
- term.write(footer)
- waitforinput()
- os.reboot()
- end
- local stargate = peripheral.wrap("stargate_5")
- if not stargate then
- catastrophicError("No Stargate Attached","Modify the program to match the situation")
- end
- --Copied from pastebin (i did write it manually at one point but it didn't work)
- local button = { --Our main button table. Contains everything from button draw functions to the button information.
- button_defaults = { --This is the metatable which we give set new buttons to. It provides color/size defaults.
- __index = {
- color_bg = colors.orange;
- color_cl = colors.blue;
- color_txt = colors.black;
- height = 3;
- padding = 2;
- isClicked = false;
- };
- };
- 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.
- __call = function(self) --This allows us to call the table as if it were a function.
- for index, btn in pairs(self.buttons) do
- if btn.enabled then
- local color = btn.isClicked and btn.color_cl or btn.color_bg
- term.setBackgroundColor(color)
- term.setTextColor(btn.color_txt)
- for yPos = btn.y, btn.bounds.y2 do
- term.setCursorPos(btn.x, yPos)
- term.write(string.rep(" ", btn.width))
- end
- local text = btn.isClicked and btn.clickText or btn.text
- term.setCursorPos(btn.x + (btn.width/2 - #text/2), btn.y + (btn.height/2))
- term.write(text)
- end
- end
- end;
- __newindex = function(t, key, value) --This changes the behavior of the table upon adding a new button
- 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
- assert(value.x, "Requires initial x")
- assert(value.y, "Requires initial y")
- assert(value.text, "Requires text value")
- setmetatable(value, t.button_defaults) --Give our new button its defaults with the __index metamethod
- value.width = #value.text + (value.padding * 2)
- value.bounds = {
- 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)
- y1 = value.y;
- x2 = value.x + value.width - 1; --In order to draw and detect clicks correctly, you need to subtract 1 from the width and height.
- y2 = value.y + value.height - 1;
- }
- 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)
- end;
- };
- checkClick = function(self, x,y) --This checks whether you have actually clicked on a table
- for index, btn in pairs(self.buttons) do
- if btn.enabled and x>=btn.x and x<=btn.bounds.x2 and y>=btn.y and y<=btn.bounds.y2 then
- btn.isClicked = true --If we have actually clicked the button then set its click value to true
- if btn.onClick then --And check if it has an onClick function
- btn:onClick() --If so, then execute it and pass the button's table/info into it by using the colon operator
- end
- return index --Return the index of the button so we can unhighlight it
- end
- end
- end;
- buttons = {}; --This is the table that we'll keep all the buttons in
- }
- setmetatable(button, button.mt) --Set the metatable of button to button.mt
- function inform(text)
- term.setBackgroundColor(colours.black)
- term.setTextColor(colours.white)
- term.setCursorPos(1,1)
- print(text)
- waitforinput()
- end
- --Gate Functions
- function toggleIris()
- local irisState = stargate.irisState()
- if irisState == "Closed" then
- stargate.openIris()
- elseif irisState == "Open" then
- stargate.closeIris()
- elseif irisState == "Offline" then
- inform("No Iris installed.")
- end
- end
- function dialMenu()
- local gateStatus = stargate.stargateState()
- if gateStatus == "Dialling" then
- inform("Currently Dialling Already")
- return
- elseif gateStatus == "Opening" or gateStatus == "Connected" or gateStatus == "Closing" then
- inform("Gate is Busy.")
- return
- end
- term.setBackgroundColor(colours.green)
- term.clear()
- term.setCursorPos(1,1)
- term.write("Enter Address:")
- term.setCursorPos(1,2)
- local address = read()
- term.setCursorPos(1,3)
- local energy = stargate.energyToDial(address)
- local curEnergy = stargate.energyAvailable()
- if not energy then
- inform(address .. " Is not an address!")
- return
- end
- term.write("It will take "..tostring(energy).." Energy.")
- energy = stargate.energyToDial(address)
- if energy > curEnergy then
- term.setCursorPos(1,4)
- term.write("Not enough energy.")
- term.setCursorPos(1,5)
- term.write("Press any key to continue.")
- waitforinput()
- return
- end
- term.setCursorPos(1,4)
- term.write("Are you sure?")
- term.setCursorPos(1,5)
- term.write("TODO: CHOICE (sorry)Uh meow")
- term.setCursorPos(1,6)
- term.write("Attempting to dial "..address)
- ok, err = pcall(stargate.dial,address)
- if not ok then
- term.setCursorPos(1,7)
- term.write("Gate Failed. Reason:")
- term.setCursorPos(1,8)
- term.write(err)
- term.setCursorPos(1,9)
- else
- term.setCursorPos(1,7)
- term.write("Happy Travels")
- end
- term.setCursorPos(1,10)
- term.write("Press Any key To continue.")
- waitforinput()
- end
- function closeGate()
- local stargateStatus, stargateEngaged, wormholeDirection = stargate.stargateState()
- if stargateStatus == "Idle" or not stargateStatus == "Connected" then
- inform("Cannot close gate at this time")
- return
- end
- if wormholeDirecton == "Outgoing" then
- inform("Cannot close incoming wormhole!")
- return
- end
- stargate.disconnect()
- end
- --GUI stuff
- button[1] = {
- x = 1;
- y = 1;
- text = "Toggle Iris";
- enabled = true;
- clickText = text;
- onClick = toggleIris;
- }
- button[2] = {
- x = 1;
- y = 5;
- text = "Dial Address";
- clickText = text;
- enabled = true;
- onClick = dialMenu;
- }
- button[3] = {
- x = 1;
- y = 9;
- text = "Close Gate";
- clickText = text;
- enabled = true;
- onClick = closeGate;
- }
- local timer = { --This will keep track of clicked buttons/the timers associated with them
- index = false;
- timer = false;
- }
- local termSize = {term.getSize()}
- function main()
- while true do
- term.setBackgroundColor(colours.grey)
- term.clear()
- button() --Always draw the button first
- term.setCursorPos(1,termSize[2]-1)
- term.setBackgroundColor(colours.blue)
- term.write("Gate Energy " .. tostring(stargate.energyAvailable()))
- term.setCursorPos(1,termSize[2])
- term.write("Gate Address " .. stargate.localAddress() .. " Connected to ".. stargate.remoteAddress())
- local e = {os.pullEvent()} --Then pull our events
- if e[1] == "mouse_click" then
- local index = button:checkClick(e[3], e[4]) --Check the click: make sure to pass the button table into the checkClick function
- if index then
- timer.index = index--The index of the button that is clicked
- timer.timer = os.startTimer(1)
- end
- 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
- button.buttons[timer.index].isClicked = false --Deselect the button
- 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
- elseif e[1] == "sgMessageRecieved" then
- inform(e[2])
- elseif e[1] == "sgStargateStateChange" then
- end
- end
- end
- --Error Handling
- xpcall(main, catastrophicError)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement