Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Computer Craft Rekia's Reactor Craft Power Manager
- --By Snipy67
- --V1.5
- --which is built ontop of
- --Computer Craft Master Application for redstone interfacing
- --By snipy67
- --V1.1
- --You will need the Node Application at http://pastebin.com/3sGZ4dB3
- --to setup the nodes you need to download the node application and make sure you have 1 computer for each entry in "NODES" below
- --I recomend you try it first with redstone lamps
- --You will need the Router Application in server mode running on the network http://pastebin.com/BuRcCc2n
- MONITOR_SIDE = "top"
- NODES = {"gen1","gen2","gasturbine","tobatfromgen","tobatfromturbine","4bat","straightout","frombat","fromgas"}
- NODES_NAME = {"Generator\n1","Generator\n2","Gas\nTurbine","Generator\nTo\nBattery","Turbine\nTo\nBattery", "Batteries","Straight\nOut From\nGenerator","Out From\nBattery","Out From\nTurbine"}
- BUTTON_SIZE_X = 8
- BUTTON_SIZE_Y = 4
- nodeState = {}
- nodePort = {}
- nodeSendPort = {}
- nodeButtons = {}
- conPort = {}
- buttons = {}
- buttonsPressed = {}
- buttonsPosition = {}
- buttonsFunc = {}
- drawLinesData = {}
- --Computer Craft Router Application
- --By snipy67
- --V1.0
- MASTER_PORT = 1
- BROADCAST_PORT = 2
- --Layer 1
- lowLevelListeners = {}
- routerComputerId = 0
- function detectModem()
- return peripheral.find("modem")
- end
- function lowLevelMessageSplit(message)
- local tab = {}
- local current = ""
- for i = 1, #message, 1 do
- if message:sub(i,i) == ':' then
- table.insert(tab,current)
- current = ""
- else
- current = current .. message:sub(i,i)
- end
- end
- if #current > 0 then
- table.insert(tab,current)
- end
- return tab
- end
- function lowLevelListenerCheckForMethod(modem,port,tab,verbose)
- for k, v in pairs(lowLevelListeners) do
- if v.message == tab[1] then
- if verbose then
- print("function " .. v.message .. "found")
- end
- if v.func ~= nil then
- local t = {}
- t.message = tab[1]
- t.senderId = tab[2]
- t.reciverId = tab[3]
- t.data = tab[4]
- v.func(t)
- if t.data ~= nil then
- local responseText = tab[1] .. "~response:" .. os.getComputerID() .. ":".. tab[2] .. ":".. t.data;
- modem.transmit(port,port,responseText)
- else
- local responseText = tab[1] .. "~response:" .. os.getComputerID() .. ":".. tab[2]
- modem.transmit(port,port,responseText)
- end
- else
- local responseText = tab[1] .. "~response:" .. os.getComputerID() .. ":".. tab[2]
- modem.transmit(port,port,responseText)
- end
- return true
- else
- if verbose then
- print("v.message:" .. v.message .. " != tab[1]:"..tab[1])
- end
- end
- end
- return false
- end
- function lowLevelListener(modem,port,verbose)
- while true do
- local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent()--listens for a actions
- if event == "modem_message" then--gets the message
- if senderChannel == port then
- if verbose then
- print("message recived: " .. message)
- end
- local tab = lowLevelMessageSplit(message)
- if #tab > 2 then
- if verbose then
- print("There is more then 2 arguments in the message")
- end
- if tonumber(tab[3]) == os.getComputerID() then
- if verbose then
- print("id matches")
- end
- lowLevelListenerCheckForMethod(modem,port,tab,verbose)
- elseif tonumber(tab[3]) == -1 then
- if verbose then
- print("broadcast")
- end
- lowLevelListenerCheckForMethod(modem,port,tab,verbose)
- end
- elseif #tab == 2 then
- lowLevelListenerCheckForMethod(modem,port,tab,verbose)
- end
- end
- end
- end
- end
- function lowLevelRequest(modem,request,port,maxTimeOut,timeBetweenResend,numberOfResendsBeforeTimeOut,id,data,verbose)
- local str = ""
- if id ~= nil and id ~= -1 then
- str = request .. ":" .. os.getComputerID() .. ":" .. id -- adds the computer id and the id of the reciver
- else
- str = request .. ":" .. os.getComputerID() .. ":" .. -1-- adds the computer id to the requests
- end
- if data ~= nil then
- str = str .. ":" .. data
- end
- modem.transmit(port,port,str);--transmits the request
- local responseText = request .. "~response"--creates text on how a response will look like
- local count = 0--count is to keep track of how many times the request timed out
- local timer = -1
- if timeBetweenResend > 0 and numberOfResendsBeforeTimeOut > 0 then
- timer = os.startTimer(timeBetweenResend) -- to keep track of the number of seconds before a time out
- end
- local atLeastOne = false--this determines if atleast one computer recived the request
- local timeOutTimer
- if maxTimeOut > 0 then
- timeOutTimer = os.startTimer(maxTimeOut)--this timer is the number of seconds it should wait for return requests
- end
- local all = {} -- this is all the data that will be returned
- all.package = {}--this is where the data from each request is stored
- while true do
- local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent()--listens for a actions
- if event == "timer" then--check if the timer is up
- local timerId = modemSide; --modemSide is the timerid when timer event is called (prevents confusion)
- if timerId == timer then--checks if the timer is the timer that handels resends
- if atLeastOne == false then--checks if there are no records recovered
- if count ~= numberOfResendsBeforeTimeOut then--check to make sure the count is not at the timeout stage
- modem.transmit(port,port,str);--transmits the request again
- count = count + 1 -- adds one to the #of time outs
- timer = os.startTimer(timeBetweenResend)--resets the timer
- if verbose then
- print("Message Transmission failed resending...")
- end
- else
- if verbose then
- print("Message Transmission failed")
- end
- all.sucess = false
- return all
- end
- end
- elseif timerId == timeOutTimer then--this is the maximum amount of time it was going to wait and not it's going to return the data
- if atLeastone == false then
- all.sucess = false
- else
- all.sucess = true
- end
- return all
- end
- elseif event == "modem_message" then--gets the message
- if senderChannel == port then
- local tab = lowLevelMessageSplit(message)
- if verbose then
- print("Modem message: " .. message)
- end
- if tab[1] == responseText then
- if tonumber(tab[3]) == os.getComputerID() then
- local p = {}
- p.sucess = true
- p.tab = tab
- atLeastOne = true
- table.insert(all.package,p)
- if verbose then
- print("This computer: " .. tab[3] .. ". Request response recived from " .. tab[2])
- end
- if timeOutTimer == -1 then
- all.sucess = true
- return all;
- end
- end
- end
- end
- end
- end
- end
- MAX_TIME_OUT = 0.8
- TIME_BETWEEN_RESENDS = 0.2
- NUMBER_OF_RESENDS = 4
- VERBOSE = false
- --easy to use methods
- --> the low level lowLevelListener returns true if atleast 1 tramission has been valid and in this case only 1 transmision
- function basicListener(modem)
- return lowLevelListener(modem,BROADCAST_PORT,VERBOSE)--this will never finish, it will listen forever
- end
- -->Low level request return
- --.sucess
- --.package[instance].sucess = true
- --.package[instance].tab = tab
- function basicBroadcast(modem,request)
- return lowLevelRequest(modem,request,BROADCAST_PORT,MAX_TIME_OUT,TIME_BETWEEN_RESENDS,NUMBER_OF_RESENDS,nil,nil,VERBOSE)--A broadcast request which will conenct to everyone
- end
- function basicRequest(modem,request,computer)
- return lowLevelRequest(modem,request,BROADCAST_PORT,MAX_TIME_OUT,TIME_BETWEEN_RESENDS,NUMBER_OF_RESENDS,computer,nil,VERBOSE)-- a message for a certian computer
- end
- function basicBroadcastWithData(modem,request,data)
- return lowLevelRequest(modem,request,BROADCAST_PORT,MAX_TIME_OUT,TIME_BETWEEN_RESENDS,NUMBER_OF_RESENDS,nil,data,VERBOSE)-- this a a broadcast with data
- end
- function basicRequestWithData(modem,request,computer,data)
- return lowLevelRequest(modem,request,BROADCAST_PORT,MAX_TIME_OUT,TIME_BETWEEN_RESENDS,NUMBER_OF_RESENDS,computer,data,VERBOSE) -- this is a message for a certian computer with data
- end
- function addActionListener(message,func)
- --function parameters required (data)
- --.message -- the message that was transmitted
- --.senderId -- the sender of the message
- --.reciverId -- the reciver of the message
- --.data -- the data that might have been passed along
- local tab = {}
- tab.message = message
- tab.func = func
- table.insert(lowLevelListeners,tab)
- return #lowLevelListeners
- end
- function removeActionListener(index)
- table.remove(lowLevelListeners,index)
- end
- --End Of Layer 1
- --Routeing layer
- portsTaken = {}
- computerId = {}
- function openBroadcastNode(modem)
- portsTaken[BROADCAST_PORT] = true
- modem.open(BROADCAST_PORT)
- end
- function portInit(modem)
- for i = 1, 128, 1 do
- portsTaken[i] = false
- if modem.isOpen(i) then
- modem.close(i)
- end
- end
- end
- function findEmptyPort(modem)
- for i = 1,128, 1 do
- if portsTaken[i] == false then
- return i
- end
- end
- return -1
- end
- function routerServer(modem)
- portInit(modem)
- openBroadcastNode(modem)
- local requestRoute = function(data)
- local port = findEmptyPort(modem)
- computerId[port] = data.senderId
- portsTaken[port] = true
- data.data = tostring(port)
- print("Port Found: " .. port)
- end
- addActionListener("addport",requestRoute)
- local deleteRoute = function(data)
- local port = tonumber(data.data)
- if port ~= nil or port ~= -1 then
- if data.senderId == computerId[port] then
- computerId[data.senderId] = -1
- portsTaken[port] = false
- data.data = "true"
- print("Port Deleted: " .. port)
- else
- data.data = "false"
- end
- end
- end
- addActionListener("removeport",deleteRoute)
- addActionListener("ping",nil)
- basicListener(modem)
- end
- function deletePort(modem,port)
- local d = basicBroadcastWithData(modem,"removeport",tostring(port))
- for k, v in pairs(d.package) do
- if #v.tab > 3 then
- local state = v.tab[4]
- if state ~=nil then
- if state == "true" then
- return true
- else
- return false
- end
- end
- end
- end
- print("router error")
- return false
- end
- function getRouterPort(modem)
- local d = basicRequest(modem,"addport",routerComputerId)
- for k, v in pairs(d.package) do
- if #v.tab > 3 then
- local p = v.tab[4]
- if p ~= nil and p ~= "" then
- return tonumber(p)
- end
- end
- end
- print("router error")
- return -1
- end
- function routerInit(modem)
- portInit(modem)
- openBroadcastNode(modem)
- local d = basicBroadcast(modem,"ping")
- if d.sucess then
- if #d.package > 0 then
- local id = -1
- for k, v in pairs(d.package) do
- if id == -1 or id == tonumber(v.tab[2]) then
- id = tonumber(v.tab[2])
- if id ~= -1 and id < 128 then
- routerComputerId = id
- return true
- end
- else
- print("Too many routers")
- return false
- end
- end
- print("unknown router Error")
- return false
- elseif #d.package == 0 then
- print("No Routers detected")
- return false
- else
- return false
- end
- else
- print("Router not found")
- return false
- end
- end
- --End of routeing layer
- --begining of master layer core
- function splitText(text)
- local textSplit = {}
- local current = ""
- for i = 1, #text, 1 do
- local currentCharecter = text:sub(i,i)
- if currentCharecter == '\n' then
- table.insert(textSplit,current)
- current = ""
- else
- current = current .. currentCharecter
- end
- end
- if current ~= "" then
- table.insert(textSplit,current)
- current = ""
- end
- return textSplit
- end
- function writeCenter(monitor,text,ypos)
- local xSize, ySize = monitor.getSize()
- monitor.setCursorPos((xSize / 2) - ((#text / 2) - 1),ypos)
- monitor.write(text)
- end
- function draw(monitor)
- monitor.clear()
- monitor.setBackgroundColor(colors.lightGray)
- monitor.setTextColor(colors.lightBlue)
- monitor.setTextScale(1)
- drawButtons(monitor)
- drawLines(monitor)
- --writeCenter(monitor,"Electrial Transformer Controller",1)
- end
- function drawButtons(monitor)
- for k, v in pairs(buttons) do
- drawButton(monitor,v)
- end
- end
- function drawButton(monitor,button)
- local originalColor = monitor.getBackgroundColor()
- if button["state"] == true then --sets the color based on it's state
- monitor.setBackgroundColor(button["color2"])
- else
- monitor.setBackgroundColor(button["color1"])
- end
- local xMiddle = math.floor(button["xSize"] / 2)--calculates the middle horizontally
- local yMiddle = math.floor(button["ySize"] / 2)--calculates the middle vertically
- local text = splitText(button["text"])--this searchs for linebreaks and then seperates them into seperate tables
- local textSizeHalfNotRounded = (#text / 2)
- local textSizeHalf = math.floor(textSizeHalfNotRounded)
- local yExit = 0
- if (textSizeHalf == textSizeHalfNotRounded) then
- yExit = (yMiddle + (textSizeHalf - 1)) + button["y"] --calculates where the y exit point is
- else
- yExit = (yMiddle + textSizeHalf) + button["y"]
- end
- local yEntry = (yMiddle - textSizeHalf) + button["y"]--calculates where the y entry point is
- local xMax = button["x"] + button["xSize"]
- local yMax = button["y"] + button["ySize"]
- for i = button["y"],yMax,1 do -- loops from the top to the bottom of the label
- monitor.setCursorPos(button["x"],i) -- sets the position of the cursor
- if i >= yEntry and i <= yExit then--checks to see if the y is at the line where the text goes
- local textIndex = (i - yEntry) + 1--calculates what index text is at based on the yPos
- local xEntry = button["x"] + (xMiddle - ((#text[textIndex] / 2)))--Finds the xEntry point based off the y
- for j = button["x"],xMax,1 do -- loops from side to side of the label
- if j >= xEntry and j < xEntry + #text[textIndex] then-- portCheck if the charecters are within x entry
- local index = (j - xEntry) + 1--gets the index of the current charecter
- local textOut = text[textIndex]:sub(index,index)--prints out the charecter
- monitor.write(textOut)
- else
- monitor.write(" ")
- end
- end
- else
- for j = button["x"],xMax,1 do -- loops from side to side of the label
- monitor.write(" ")--writes blank
- end
- end
- end
- monitor.setBackgroundColor(originalColor)
- end
- function addButton(text,x,y,xSize,ySize,color1,color2,func)
- local button = {}
- button["text"] = text
- button["state"] = false
- button["x"] = x
- button["y"] = y
- button["xSize"] = xSize
- button["ySize"] = ySize
- button["color1"] = color1
- button["color2"] = color2
- button["func"] = func
- table.insert(buttons,button)
- return #buttons
- end
- function removeButton(index)
- table.remove(buttons,index)
- end
- function removeAllButtons()
- if #buttons ~= 0 then
- buttons = {}
- end
- end
- function GetNumberOfDigits(number)
- if number > 0 then
- return math.log10(number) + 1
- else
- return 1
- end
- end
- function allNodesPresent()
- for k, v in pairs(NODES) do
- if nodeState[v] == nil or nodeState[v] == false then
- return false
- end
- end
- return true
- end
- function checkIfNode(message)
- for k, v in pairs(NODES) do
- if message == v then
- return true
- end
- end
- return false
- end
- function isNodePort(channel)
- for k, v in pairs(nodePort) do
- if channel == tonumber(v) then
- return k
- end
- end
- return -1
- end
- function listen(monitor,modem)
- while true do
- local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent()
- if event == "modem_message" then
- if senderChannel == 1 then
- if message == "~connect~" then
- print("Connection request recived")
- local port = getRouterPort(modem)
- if port ~= -1 then
- modem.open(port)
- conPort[port] = replyChannel
- print("connection established. returned response port: " .. port)
- modem.transmit(replyChannel,port,"~connected~")
- else
- print("a device could not connect to the server, can't find valid port")
- modem.transmit(replyChannel,1,"~connection-error~")
- end
- end
- else
- if conPort[senderChannel] ~= nil then
- local index = isNodePort(senderChannel)
- --local index = conPort[senderChannel]
- if index ~= -1 then
- if message == "~close-connection" then
- print("closeing connection")
- closeConnection(index,monitor,modem,false)
- end
- else
- if checkIfNode(message) == true then
- print("Node Connecting")
- if nodeState[message] == nil or nodeState[message] == false then
- nodeState[message] = true
- nodePort[message] = senderChannel
- nodeSendPort[message] = replyChannel
- buttons[nodeButtons[message]]["state"] = true
- modem.transmit(replyChannel,senderChannel,"~NodeAccepted~")
- print("Node Accepted")
- draw(monitor)
- if allNodesPresent() then
- addActiveButtons(monitor)
- activateAlreadyPressedButtons(monitor,modem)
- onAllNodesPresent()
- end
- draw(monitor)
- else
- print("Node Not Accepted")
- modem.transmit(replyChannel,senderChannel,"~NodeNotAccepted~")
- end
- else
- modem.transmit(replyChannel,senderChannel,"~NodeNotAccepted~")
- end
- end
- end
- end
- elseif event == "monitor_touch" then
- local x = senderChannel
- local y = replyChannel
- for k, v in pairs(buttons) do
- local xMax = v["x"] + v["xSize"]
- local yMax = v["y"] + v["ySize"]
- if x >= v["x"] and x <= xMax and y >= v["y"] and y <= yMax then
- v["func"](monitor,modem,v)
- break
- end
- end
- elseif event == "key" then
- local key = modemSide
- local held = senderChannel
- if key == 31 then
- print("closeing connections")
- closeConnectionAll(monitor,modem,true)
- print("closeing program")
- break
- end
- end
- end
- end
- function transmitMessage(messageForTransmission,index,monitor,modem)
- if nodeState[index] == true then
- local timer = os.startTimer(1)
- local loop = 0
- modem.transmit(nodeSendPort[index],nodePort[index],messageForTransmission)
- while true do
- local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent()
- if event == "timer" then
- if modemSide == timer then
- print("Connection failed, retransmitting")
- if loop >= 5 then
- print("Connection failed, assumeing node is shutdown, shuting down system...")
- closeConnection(index,monitor,modem,false)
- return false
- else
- modem.transmit(nodeSendPort[index],nodePort[index],messageForTransmission)
- timer = os.startTimer(0.5)
- loop = loop + 1
- end
- end
- elseif event == "modem_message" then
- if senderChannel == nodePort[index] and replyChannel == nodeSendPort[index] then
- if message == "~Operation-Complete~" then
- break
- elseif message == "~close-connection~" then
- closeConnection(index,monitor,modem,false)
- return false
- end
- end
- end
- end
- end
- return true
- end
- function closeConnection(index,monitor,modem,transmit)
- local nodesPresent = allNodesPresent()
- if transmit then
- transmitMessage("~close-connection~",index,monitor,modem)
- end
- nodeState[index] = false
- modem.close(nodePort[index])
- buttons[nodeButtons[index]]["state"] = false
- if nodesPresent then
- transmitMessageToAll("redstone-off",monitor,modem)
- saveState()
- onAllNodesNotPresent()
- addNodes(monitor)
- end
- deletePort(modem,conPort[index])
- conPort[index] = -1
- draw(monitor)
- end
- function closeConnectionAll(monitor,modem,transmit)
- for k, v in pairs(NODES) do
- if nodeState[v] == true then
- closeConnection(v,monitor,modem,transmit)
- end
- end
- end
- function transmitMessageToAll(message,monitor,modem)
- for k, v in pairs(NODES) do
- if nodeState[v] then
- local state = transmitMessage(message,v,monitor,modem)
- if message ~= "~close-connection~" and state == false then
- break
- end
- end
- end
- end
- function activateAlreadyPressedButtons(monitor,modem)
- for k, v in pairs(NODES) do
- loadButtonState(monitor,modem,v,buttonsPressed[v])
- end
- end
- function addActiveButtons(modem)
- nodeButtons = {}
- removeAllButtons()
- for k, v in pairs(NODES) do
- nodeButtons[v] = addButton(NODES_NAME[k] .. "\noff",buttonsPosition[v].x,buttonsPosition[v].y,BUTTON_SIZE_X,BUTTON_SIZE_Y,colors.red,colors.green,buttonsFunc[v])
- end
- end
- function nodeFunctions()
- local nodeFunc = {}
- for k, v in pairs(NODES) do
- nodeFunc[v] = function(monitor,modem,button)
- end
- end
- return nodeFunc
- end
- function SetConnectedNodesColor()
- for k, v in pairs(NODES) do
- if nodeState[v] ~= nil then
- buttons[nodeButtons[v]]["state"] = nodeState[v]
- end
- end
- end
- function addNodes(monitor)
- nodeButtons = {}
- local nodeFunc = nodeFunctions()
- removeAllButtons()
- for k, v in pairs(NODES) do
- nodeButtons[v] = addButton(NODES_NAME[k],buttonsPosition[v].x,buttonsPosition[v].y,BUTTON_SIZE_X,BUTTON_SIZE_Y,colors.red,colors.green,nodeFunc[v])
- end
- SetConnectedNodesColor()
- end
- function calculateButtonPositions(monitor)
- local buttonsPos = {}
- local xPos = 2
- local yPos = 9
- for k, v in pairs(NODES) do
- local buttonPos = {}
- buttonPos.x = xPos
- buttonPos.y = yPos
- buttonsPos[v] = buttonPos
- if (xPos + 10) < monitor.getSize() then
- xPos = xPos + 10
- else
- xPos = 2
- yPos = yPos + 6
- end
- end
- buttonsPosition = buttonsPos
- end
- function placeButtonManually(index,x,y)
- local buttonPos = {}
- buttonPos.x = x
- buttonPos.y = y
- buttonsPosition[index] = buttonPos
- end
- function drawLine(monitor,x,y,xSize,ySize,color)
- local originalColor = monitor.getBackgroundColor()
- monitor.setBackgroundColor(color)
- local xMax = x + xSize
- local yMax = y + ySize
- for i = y,yMax,1 do
- monitor.setCursorPos(x,i)
- for j = x,xMax,1 do
- monitor.write(" ")
- end
- end
- monitor.setBackgroundColor(originalColor)
- end
- function drawLines(monitor)
- --this is where you can place any lines you want drawn
- for k, v in pairs(drawLinesData) do
- drawLine(monitor,v.x,v.y,v.xSize,v.ySize,v.color)
- end
- end
- function addLine(index,x,y,xSize,ySize,color)
- local item = {}
- item.x = x
- item.y = y
- item.xSize = xSize
- item.ySize = ySize
- item.color = color
- drawLinesData[index] = item
- end
- function loadButtonState(monitor,modem,index,state)
- if state == true then
- local button = buttons[nodeButtons[index]]
- button["state"] = true
- local text = splitText(button["text"])
- button["text"] = ""
- for i = 1,#text - 1 do
- button["text"] = button["text"] .. text[i] .. "\n"
- end
- button["text"] = button["text"] .. "on"
- transmitMessage("redstone-on",index,monitor,modem)
- end
- draw(monitor)
- end
- function addButtonActionFunction(index,func)
- buttonsFunc[index] = function(monitor,modem,button)
- if button["state"] == false then
- button["state"] = true
- buttonsPressed[index] = true
- local text = splitText(button["text"])
- button["text"] = ""
- for i = 1,#text - 1 do
- button["text"] = button["text"] .. text[i] .. "\n"
- end
- button["text"] = button["text"] .. "on"
- transmitMessage("redstone-on",index,monitor,modem)
- if func ~= nil then
- func(monitor,modem,button,true)
- end
- saveState()
- else
- button["state"] = false
- buttonsPressed[index] = false
- local text = splitText(button["text"])
- button["text"] = ""
- for i = 1, #text - 1 do
- button["text"] = button["text"] .. text[i] .. "\n"
- end
- button["text"] = button["text"] .. "off"
- transmitMessage("redstone-off",index,monitor,modem)
- if func ~= nil then
- func(monitor,modem,button,false)
- end
- saveState()
- end
- draw(monitor)
- end
- end
- function generateDefaultButtonActions()
- for k, v in pairs(NODES) do
- addButtonActionFunction(v,nil)
- end
- end
- function loadState()
- local f = io.open("latest_state.txt", "r")
- local map = {}
- if f then
- local s = f:read("*a")
- f:close()
- local k = ""
- local v = ""
- local state = false
- local failed = false
- for i = 1, #s, 1 do
- if s:sub(i,i) == ':' then
- if state == false then
- state = true
- else
- print("io exception, too many :")
- failed = true
- break
- end
- elseif s:sub(i,i) == ',' then
- if state == true then
- state = false
- if v == "true" then
- map[k] = true
- elseif v == "false" then
- map[k] = false
- else
- print("result is not true or false")
- failed = true
- break
- end
- k = ""
- v = ""
- else
- print("io exception, no key")
- failed = true
- break
- end
- else
- if state then
- v = v .. s:sub(i,i)
- else
- k = k .. s:sub(i,i)
- end
- end
- end
- if failed == false then
- if #map == #NODES then
- for k, v in pairs(NODES) do
- if map[v] == nil then
- failed = true
- break
- end
- end
- else
- failed = true
- end
- end
- end
- return map
- end
- function saveState()
- local file = io.open("latest_state.txt" , "w")
- for k, v in pairs(buttonsPressed) do
- file:write(k .. ":" .. tostring(v) .. ",")
- end
- file:flush()
- file:close()
- end
- --end of Master Layers core
- --begining of Master Layers config layer
- function onAllNodesPresent()
- --allows you to config what happends when all nodes become present
- drawCorespondingLines()
- end
- function onAllNodesNotPresent()
- --allows you to config what happends when one node leaves when all nodes were present
- resetCorespondingLineColors()
- end
- function setupButtonActionsManually()
- --if you want to customize what happends when you select a button
- --Example:addButtonActionFunction(index,func<(monitor,modem,button,newState)>)
- addButtonActionFunction("gen1",function(monitor,modem,button,newState)
- if newState then
- if buttons[nodeButtons["gen2"]]["state"] == false then
- buttons[nodeButtons["gen2"]]["func"](monitor,modem,buttons[nodeButtons["gen2"]])
- end
- else
- if buttons[nodeButtons["gen2"]]["state"] then
- buttons[nodeButtons["gen2"]]["func"](monitor,modem,buttons[nodeButtons["gen2"]])
- end
- end
- resetCorespondingLineColors()
- drawCorespondingLines()
- end)
- addButtonActionFunction("gen2",function(monitor,modem,button,newState)
- if newState then
- if buttons[nodeButtons["gen1"]]["state"] == false then
- buttons[nodeButtons["gen1"]]["func"](monitor,modem,buttons[nodeButtons["gen1"]])
- end
- else
- if buttons[nodeButtons["gen1"]]["state"] then
- buttons[nodeButtons["gen1"]]["func"](monitor,modem,buttons[nodeButtons["gen1"]])
- end
- end
- resetCorespondingLineColors()
- drawCorespondingLines()
- end)
- addButtonActionFunction("gasturbine",function(monitor,modem,button,newState)
- resetCorespondingLineColors()
- drawCorespondingLines()
- end)
- addButtonActionFunction("tobatfromgen",function(monitor,modem,button,newState)
- if newState then
- if buttons[nodeButtons["tobatfromturbine"]]["state"] then
- buttons[nodeButtons["tobatfromturbine"]]["func"](monitor,modem,buttons[nodeButtons["tobatfromturbine"]])
- end
- end
- resetCorespondingLineColors()
- drawCorespondingLines()
- end)
- addButtonActionFunction("tobatfromturbine",function(monitor,modem,button,newState)
- if newState then
- if buttons[nodeButtons["tobatfromgen"]]["state"] then
- buttons[nodeButtons["tobatfromgen"]]["func"](monitor,modem,buttons[nodeButtons["tobatfromgen"]])
- end
- end
- resetCorespondingLineColors()
- drawCorespondingLines()
- end)
- addButtonActionFunction("4bat",function(monitor,modem,button,newState)
- resetCorespondingLineColors()
- drawCorespondingLines()
- end)
- addButtonActionFunction("straightout",function(monitor,modem,button,newState)
- if newState then
- if buttons[nodeButtons["frombat"]]["state"] then
- buttons[nodeButtons["frombat"]]["func"](monitor,modem,buttons[nodeButtons["frombat"]])
- end
- if buttons[nodeButtons["fromgas"]]["state"] then
- buttons[nodeButtons["fromgas"]]["func"](monitor,modem,buttons[nodeButtons["fromgas"]])
- end
- end
- resetCorespondingLineColors()
- drawCorespondingLines()
- end)
- addButtonActionFunction("frombat",function(monitor,modem,button,newState)
- if newState then
- if buttons[nodeButtons["straightout"]]["state"] then
- buttons[nodeButtons["straightout"]]["func"](monitor,modem,buttons[nodeButtons["straightout"]])
- end
- if buttons[nodeButtons["fromgas"]]["state"] then
- buttons[nodeButtons["fromgas"]]["func"](monitor,modem,buttons[nodeButtons["fromgas"]])
- end
- end
- resetCorespondingLineColors()
- drawCorespondingLines()
- end)
- addButtonActionFunction("fromgas",function(monitor,modem,button,newState)
- if newState then
- if buttons[nodeButtons["frombat"]]["state"] then
- buttons[nodeButtons["frombat"]]["func"](monitor,modem,buttons[nodeButtons["frombat"]])
- end
- if buttons[nodeButtons["straightout"]]["state"] then
- buttons[nodeButtons["straightout"]]["func"](monitor,modem,buttons[nodeButtons["straightout"]])
- end
- end
- resetCorespondingLineColors()
- drawCorespondingLines()
- end)
- end
- function resetCorespondingLineColors()
- for k, v in pairs(drawLinesData) do
- v.color = colors.red
- end
- end
- --changes the colors of the lines depending what is switch on or off
- function drawCorespondingLines()
- --drawLinesData[index]
- --buttonsPressed[index]
- if buttonsPressed["gen1"] and buttonsPressed["gen2"] then
- if buttonsPressed["straightout"] then
- drawLinesData["gen1out"].color = colors.green
- drawLinesData["gen1intersection"].color = colors.green
- drawLinesData["gentostraightout"].color = colors.green
- drawLinesData["gen2out"].color = colors.green
- drawLinesData["genconnection"].color = colors.green
- drawLinesData["gen2intersection"].color = colors.green
- end
- if buttonsPressed["tobatfromgen"] then
- drawLinesData["gen1out"].color = colors.green
- drawLinesData["gen1intersection"].color = colors.green
- drawLinesData["genconnection"].color = colors.green
- drawLinesData["gen2intersection"].color = colors.green
- drawLinesData["gentobattery"].color = colors.green
- drawLinesData["gen2out"].color = colors.green
- end
- elseif buttonsPressed["gen1"] then
- if buttonsPressed["straightout"] then
- drawLinesData["gen1out"].color = colors.green
- drawLinesData["gen1intersection"].color = colors.green
- drawLinesData["gentostraightout"].color = colors.green
- end
- if buttonsPressed["tobatfromgen"] then
- drawLinesData["gen1out"].color = colors.green
- drawLinesData["gen1intersection"].color = colors.green
- drawLinesData["genconnection"].color = colors.green
- drawLinesData["gen2intersection"].color = colors.green
- drawLinesData["gentobattery"].color = colors.green
- end
- elseif buttonsPressed["gen2"] then
- if buttonsPressed["straightout"] then
- drawLinesData["gen2out"].color = colors.green
- drawLinesData["gen2intersection"].color = colors.green
- drawLinesData["genconnection"].color = colors.green
- drawLinesData["gen1intersection"].color = colors.green
- drawLinesData["gentostraightout"].color = colors.green
- end
- if buttonsPressed["tobatfromgen"] then
- drawLinesData["gen2out"].color = colors.green
- drawLinesData["gen2intersection"].color = colors.green
- drawLinesData["gentobattery"].color = colors.green
- end
- end
- if buttonsPressed["gasturbine"] then
- if buttonsPressed["fromgas"] then
- drawLinesData["turbineoutline1"].color = colors.green
- drawLinesData["turbinestraightout1"].color = colors.green
- drawLinesData["turbinestraightout2"].color = colors.green
- drawLinesData["turbinestraightout3"].color = colors.green
- drawLinesData["turbinestraightout4"].color = colors.green
- drawLinesData["turbinestraightout5"].color = colors.green
- end
- if buttonsPressed["tobatfromturbine"] then
- drawLinesData["turbineoutline1"].color = colors.green
- drawLinesData["turbineoutlinetobat2"].color = colors.green
- drawLinesData["turbineoutlinetobat3"].color = colors.green
- end
- end
- if buttonsPressed["tobatfromgen"] then
- if buttonsPressed["gen1"] or buttonsPressed["gen2"] then
- drawLinesData["genToBat1"].color = colors.green
- drawLinesData["genToBat2"].color = colors.green
- drawLinesData["genToBat3"].color = colors.green
- end
- end
- if buttonsPressed["tobatfromturbine"] then
- if buttonsPressed["gasturbine"] then
- drawLinesData["turbineToBat1"].color = colors.green
- drawLinesData["turbineToBat2"].color = colors.green
- drawLinesData["turbineToBat3"].color = colors.green
- end
- end
- if buttonsPressed["4bat"] then
- if buttonsPressed["frombat"] then
- drawLinesData["bat1"].color = colors.green
- end
- end
- if buttonsPressed["straightout"] then
- if buttonsPressed["gen1"] or buttonsPressed["gen2"] then
- drawLinesData["outline"].color = colors.green
- drawLinesData["outlineconnection"].color = colors.green
- drawLinesData["lineout"].color = colors.green
- end
- end
- if buttonsPressed["frombat"] then
- if buttonsPressed["4bat"] then
- drawLinesData["batline"].color = colors.green
- drawLinesData["lineout"].color = colors.green
- end
- end
- if buttonsPressed["fromgas"] then
- if buttonsPressed["gasturbine"] then
- drawLinesData["gasline"].color = colors.green
- drawLinesData["gaslineconnection"].color = colors.green
- drawLinesData["lineout"].color = colors.green
- end
- end
- end
- function setupLines()
- --this is a mess, taking positions from anywhere I could reference them gg understanding it
- local gen1StartPosX = buttonsPosition["gen1"].x + BUTTON_SIZE_X
- local gen1StartPosY = buttonsPosition["gen1"].y + (BUTTON_SIZE_Y / 2)
- local gen2StartPosX = buttonsPosition["gen2"].x + BUTTON_SIZE_X
- local gen2StartPosY = buttonsPosition["gen2"].y + (BUTTON_SIZE_Y / 2)
- local genStraightOutPosX = buttonsPosition["straightout"].x
- --generator lines
- addLine("gen1out",gen1StartPosX + 1,gen1StartPosY,0,0,colors.red)
- addLine("gen1intersection",gen1StartPosX + 2,gen1StartPosY,0,0,colors.red)
- addLine("gen2out",gen2StartPosX + 1,gen2StartPosY,0,0,colors.red)
- addLine("gen2intersection",gen2StartPosX + 2,gen2StartPosY,0,0,colors.red)
- addLine("genconnection",gen1StartPosX + 2,gen1StartPosY + 1,0,3,colors.red)
- addLine("gentobattery",gen1StartPosX + 3, gen1StartPosY + 5,2,0,colors.red)
- addLine("gentostraightout",gen1StartPosX + 3,gen1StartPosY,genStraightOutPosX - gen1StartPosX - 4,0,colors.red)
- --gas turbine lines
- local turbineStartPosX = buttonsPosition["gasturbine"].x + BUTTON_SIZE_X
- local turbineStartPosY = buttonsPosition["gasturbine"].y + (BUTTON_SIZE_Y / 2)
- local toBatFromTurbinePosY = buttonsPosition["tobatfromturbine"].y + (BUTTON_SIZE_Y / 2)
- local toBatFromTurbinePosX = buttonsPosition["tobatfromturbine"].x + BUTTON_SIZE_X
- local straightOutFromTurbinePosY = buttonsPosition["fromgas"].y + (BUTTON_SIZE_Y / 2)
- local straightOutFromTurbinePosX = buttonsPosition["fromgas"].x
- addLine("turbineoutline1",turbineStartPosX + 1,turbineStartPosY,1,0,colors.red)
- addLine("turbineoutlinetobat2",turbineStartPosX + 2,turbineStartPosY - 2,0,2,colors.red)
- addLine("turbineoutlinetobat3",turbineStartPosX + 2,toBatFromTurbinePosY,3,0,colors.red)
- addLine("turbinestraightout1",turbineStartPosX + 2,straightOutFromTurbinePosY,1,0,colors.red)
- addLine("turbinestraightout2",turbineStartPosX + 3,straightOutFromTurbinePosY + 1,0,0,colors.red)
- addLine("turbinestraightout3",turbineStartPosX + 3,straightOutFromTurbinePosY + 2,toBatFromTurbinePosX - (turbineStartPosX + 3) + 2,0,colors.red)
- addLine("turbinestraightout4",toBatFromTurbinePosX + 2,straightOutFromTurbinePosY,0,1,colors.red)
- addLine("turbinestraightout5",toBatFromTurbinePosX + 3,straightOutFromTurbinePosY,straightOutFromTurbinePosX - toBatFromTurbinePosX - 4,0,colors.red)
- --battery lines
- local genToBatPosX = buttonsPosition["tobatfromgen"].x + BUTTON_SIZE_X
- local genToBatPosY = buttonsPosition["tobatfromgen"].y + (BUTTON_SIZE_Y / 2)
- local turbineToBatPosX = buttonsPosition["tobatfromturbine"].x + BUTTON_SIZE_X
- local turbineToBatPosY = buttonsPosition["tobatfromturbine"].y + (BUTTON_SIZE_Y / 2)
- local batPosX = buttonsPosition["4bat"].x + BUTTON_SIZE_X
- local batPosY = buttonsPosition["4bat"].y + (BUTTON_SIZE_Y / 2)
- local batOutPosX = buttonsPosition["frombat"].x
- local batOutPosY = buttonsPosition["frombat"].y + (BUTTON_SIZE_Y / 2)
- addLine("genToBat1",genToBatPosX + 1,genToBatPosY - 1,1,0,colors.red)
- addLine("genToBat2",genToBatPosX + 2,genToBatPosY,0,0,colors.red)
- addLine("genToBat3",genToBatPosX + 2,genToBatPosY + 1,(batPosX - BUTTON_SIZE_X) - turbineToBatPosX - 3,0,colors.red)
- addLine("turbineToBat1",turbineToBatPosX + 1,turbineToBatPosY + 1,1,0,colors.red)
- addLine("turbineToBat2",turbineToBatPosX + 2,turbineToBatPosY -2,0,3,colors.red)
- addLine("turbineToBat3",turbineToBatPosX + 2,turbineToBatPosY -2,(batPosX - BUTTON_SIZE_X) - turbineToBatPosX - 3,0,colors.red)
- addLine("bat1",batPosX + 1,batPosY,batOutPosX - batPosX - 2,0,colors.red)
- --all outputs
- local outLinePosX = buttonsPosition["straightout"].x + BUTTON_SIZE_X
- local outLinePosY = buttonsPosition["straightout"].y + (BUTTON_SIZE_Y / 2)
- local batLineOutPosX = buttonsPosition["frombat"].x + BUTTON_SIZE_X
- local batLineOutPosY = buttonsPosition["frombat"].y + (BUTTON_SIZE_Y / 2)
- local gasLineOutPosX = buttonsPosition["fromgas"].x + BUTTON_SIZE_X
- local gasLineOutPosY = buttonsPosition["fromgas"].y + (BUTTON_SIZE_Y / 2)
- addLine("outline",outLinePosX + 1,outLinePosY,0,0,colors.red)
- addLine("outlineconnection",outLinePosX + 2,outLinePosY,0,batLineOutPosY - outLinePosY - 1,colors.red)
- addLine("batline",batLineOutPosX + 1,batLineOutPosY,0,0,colors.red)
- addLine("gasline",gasLineOutPosX + 1,gasLineOutPosY,0,0,colors.red)
- addLine("lineout",batLineOutPosX + 2,batLineOutPosY,1,0,colors.red)
- addLine("gaslineconnection",batLineOutPosX + 2,batLineOutPosY + 1,0,gasLineOutPosY - batLineOutPosY - 1,colors.red)
- end
- --NODES = {"gen1","gen2","gasturbine","tobatfromgen","tobatfromturbine","4bat","straightout","frombat","fromgas"}
- function placeButtonsManually()
- --if you want to setup a custom button configuration you can do it here
- --example: placeButtonManually("NAME_OF_NODE",x,y)
- placeButtonManually("gen1",2,2)
- placeButtonManually("gen2",2,7)
- placeButtonManually("gasturbine",2,14)
- placeButtonManually("tobatfromgen",16,6)
- placeButtonManually("tobatfromturbine",16,11)
- placeButtonManually("4bat",28,8)
- placeButtonManually("straightout",39,2)
- placeButtonManually("frombat",39,8)
- placeButtonManually("fromgas",39,14)
- end
- function drawMonitor()
- local monitor = peripheral.wrap(MONITOR_SIDE)
- --setup
- --generateDefaultButtonActions() -- this will generate the default actions which turns then green to red
- --calculateButtonPositions(monitor) -- this will place the buttons automaticly based on the monitor
- setupButtonActionsManually()
- placeButtonsManually()
- setupLines()
- addNodes(monitor)
- draw(monitor)
- --test(monitor)
- return monitor
- end
- --end of master Layer config
- function runMaster()
- local modem = detectModem()
- routerInit(modem)
- modem.open(1)
- local monitor = drawMonitor()
- buttonsPressed = loadState()
- listen(monitor,modem)
- end
- runMaster()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement