Completed functioning stuff

This commit is contained in:
Andrew Lalis 2023-09-14 19:06:16 -04:00
parent 58c65c3037
commit c4508def1a
2 changed files with 110 additions and 65 deletions

View File

@ -8,8 +8,8 @@ local RECEIVE_CHANNEL = 45452
-- ONLY FOR DEBUGGING -- ONLY FOR DEBUGGING
-- inspect = require("inspect") -- inspect = require("inspect")
-- local modem = peripheral.wrap("top") or error("Missing top modem") local modem = peripheral.wrap("top") or error("Missing top modem")
-- modem.open(RECEIVE_CHANNEL) modem.open(RECEIVE_CHANNEL)
local function generateStandardNode(id, edgeIds) local function generateStandardNode(id, edgeIds)
local node = {id = id, connections = {}, type = "JUNCTION"} local node = {id = id, connections = {}, type = "JUNCTION"}
@ -23,9 +23,10 @@ local function generateStandardNode(id, edgeIds)
return node return node
end end
local function generateStationNode(id, edgeId) local function generateStationNode(id, displayName, edgeId)
return { return {
id = id, id = id,
displayName = displayName,
connections = { connections = {
{from = nil, to = edgeId}, {from = nil, to = edgeId},
{from = edgeId, to = nil} {from = edgeId, to = nil}
@ -40,7 +41,7 @@ local function loadGraph()
-- g = textutils.unserialize(f:read("*a")) -- g = textutils.unserialize(f:read("*a"))
-- f:close() -- f:close()
--return g --return g
return { local tempGraph = {
nodes = { nodes = {
generateStandardNode("Junction-HandieVale", {"handievale", "N1", "W1"}), generateStandardNode("Junction-HandieVale", {"handievale", "N1", "W1"}),
generateStandardNode("Junction-Middlecross", {"W1", "N2", "W2", "S1"}), generateStandardNode("Junction-Middlecross", {"W1", "N2", "W2", "S1"}),
@ -48,10 +49,10 @@ local function loadGraph()
generateStandardNode("Junction-End", {"E1", "E2", "end"}), generateStandardNode("Junction-End", {"E1", "E2", "end"}),
generateStandardNode("Junction-Klausville", {"N3", "N4", "klausville"}), generateStandardNode("Junction-Klausville", {"N3", "N4", "klausville"}),
generateStandardNode("Junction-Foundry-West", {"W3", "foundry", "W4"}), generateStandardNode("Junction-Foundry-West", {"W3", "foundry", "W4"}),
generateStationNode("station-klausville", "klausville"), generateStationNode("station-klausville", "Klausville", "klausville"),
generateStationNode("station-handievale", "handievale"), generateStationNode("station-handievale", "HandieVale", "handievale"),
generateStationNode("station-end", "end"), generateStationNode("station-end", "End & Biofuel Refinery", "end"),
generateStationNode("station-foundry", "foundry") generateStationNode("station-foundry", "Jack's Foundry", "foundry")
}, },
edges = { edges = {
{id = "handievale", length = 16}, {id = "handievale", length = 16},
@ -70,6 +71,7 @@ local function loadGraph()
{id = "N4", length = nil} {id = "N4", length = nil}
} }
} }
return tempGraph
end end
local function filterTable(arr, func) local function filterTable(arr, func)
@ -296,7 +298,7 @@ local function handleRequests(graph)
end end
end end
-- handleRequests(loadGraph()) handleRequests(loadGraph())
-- local graph = loadGraph() -- local graph = loadGraph()
-- print("GRAPH:") -- print("GRAPH:")

View File

@ -31,11 +31,18 @@ local function broadcastRoute(route)
end end
end end
local function isValidStationInfo(msg)
return msg ~= nil and
msg.name ~= nil and type(msg.name) == "string" and
msg.range ~= nil and type(msg.range) == "number" and
msg.displayName ~= nil and type(msg.displayName) == "string"
end
-- Repeats until we are within range of a station that's sending out its info. -- Repeats until we are within range of a station that's sending out its info.
local function waitForStation(stationName) local function waitForStation(stationName)
while true do while true do
local event, side, channel, replyChannel, msg, dist = os.pullEvent("modem_message") local event, side, channel, replyChannel, msg, dist = os.pullEvent("modem_message")
if channel == STATION_BROADCAST_CHANNEL and msg and msg.name == stationName and msg.range >= dist then if channel == STATION_BROADCAST_CHANNEL and isValidStationInfo(msg) and msg.name == stationName and msg.range >= dist then
return return
end end
end end
@ -44,7 +51,7 @@ end
local function listenForAnyStation() local function listenForAnyStation()
while true do while true do
local event, side, channel, replyChannel, msg, dist = os.pullEvent("modem_message") local event, side, channel, replyChannel, msg, dist = os.pullEvent("modem_message")
if channel == STATION_BROADCAST_CHANNEL and msg and msg.range >= dist then if channel == STATION_BROADCAST_CHANNEL and isValidStationInfo(msg) and msg.range >= dist then
os.queueEvent("rail_station_nearby", msg, dist) os.queueEvent("rail_station_nearby", msg, dist)
end end
end end
@ -87,63 +94,81 @@ local function waitForModemMessage(expectedReplyChannel, timeout)
return data return data
end end
local function drawLookingForStationScreen()
g.clear(term, colors.white)
g.drawText(term, 1, 1, "Looking for nearby station", colors.black, colors.yellow)
g.drawText(term, 1, 2, "Walk near a station to", colors.gray, colors.white)
g.drawText(term, 1, 3, "see available routes.", colors.gray, colors.white)
end
local function drawStationFoundScreen(stationName)
g.clear(term, colors.white)
g.drawXLine(term, 1, W, 1, colors.lightBlue)
g.drawText(term, 1, 1, "Found a station!", colors.black, colors.lightBlue)
g.drawText(term, 1, 3, stationName, colors.blue, colors.white)
g.drawText(term, 1, 5, "Fetching routes...", colors.gray, colors.white)
end
local function drawDestinationsChoiceScreen(choices)
g.clear(term, colors.white)
g.drawXLine(term, 1, W, 1, colors.blue)
g.drawText(term, 1, 1, "Destinations", colors.white, colors.blue)
g.drawText(term, W-3, 1, "Quit", colors.white, colors.red)
for i, choice in pairs(choices) do
local y = i + 1
local bg = colors.white
if i % 2 == 0 then bg = colors.lightGray end
g.drawXLine(term, 1, W, y, bg)
g.drawText(term, 1, y, i..". "..choice, colors.black, bg)
end
end
local function drawErrorPage(errorMsg)
g.clear(term, colors.white)
g.drawXLine(term, 1, W, 1, colors.red)
g.drawText(term, 1, 1, "Error", colors.white, colors.red)
term.setCursorPos(1, 2)
term.setTextColor(colors.black)
term.setBackgroundColor(colors.white)
print(errorMsg)
local x, y = term.getCursorPos()
term.setCursorPos(1, y + 1)
print("Click to dismiss")
parallel.waitForAny(
function () os.sleep(5) end,
function () os.pullEvent("mouse_click") end
)
end
local function handleNearbyStation() local function handleNearbyStation()
while true do while true do
g.clear(term, colors.white) drawLookingForStationScreen()
g.drawText(term, 1, 1, "Looking for nearby station", colors.black, colors.yellow)
g.drawText(term, 1, 2, "Walk near a station to", colors.gray, colors.white)
g.drawText(term, 1, 3, "see available routes.", colors.gray, colors.white)
os.sleep(1)
local event, stationData, dist = os.pullEvent("rail_station_nearby") local event, stationData, dist = os.pullEvent("rail_station_nearby")
g.clear(term, colors.white) drawStationFoundScreen(stationData.displayName)
g.drawXLine(term, 1, W, 1, colors.lightBlue) os.sleep(0.5)
g.drawText(term, 1, 1, "Found a station!", colors.black, colors.lightBlue)
g.drawText(term, 1, 3, stationData.name, colors.blue, colors.white)
g.drawText(term, 1, 5, "Fetching routes...", colors.gray, colors.white)
os.sleep(1)
modem.transmit(STATION_REQUEST_CHANNEL, MY_CHANNEL, "GET_ROUTES") modem.transmit(SERVER_CHANNEL, MY_CHANNEL, {command = "GET_ROUTES", startNode = stationData.name})
local response = waitForModemMessage(STATION_REQUEST_CHANNEL, 1) local response = waitForModemMessage(SERVER_CHANNEL, 3)
if not response or not response.msg or type(response.msg) ~= "table" then if response and response.msg.success then
g.clear(term, colors.white) local stations = response.msg.stations
g.drawXLine(term, 1, W, 1, colors.red) local stationNames = {}
g.drawText(term, 1, 1, "Error", colors.white, colors.red) local stationIds = {}
g.drawText(term, 1, 2, "Failed to get routes.", colors.gray, colors.white) for _, station in pairs(stations) do
if response then table.insert(stationNames, station.displayName)
term.setCursorPos(1, 3) table.insert(stationIds, station.id)
term.setTextColor(colors.black)
term.setBackgroundColor(colors.lightGray)
print("Response:"..textutils.serialize(response, {compact=true}))
end end
os.sleep(5) drawDestinationsChoiceScreen(stationNames)
else local destination = nil
local routes = response.msg -- Wait for user to choose destination, quit, or go away from station.
g.clear(term, colors.white)
g.drawXLine(term, 1, W, 1, colors.blue)
g.drawText(term, 1, 1, "Routes", colors.white, colors.blue)
g.drawText(term, W-3, 1, "Quit", colors.white, colors.red)
for i, route in pairs(routes) do
local y = i + 1
local bg = colors.white
if i % 2 == 0 then bg = colors.lightGray end
g.drawXLine(term, 1, W, y, bg)
g.drawText(term, 1, y, i..". "..route.name, colors.black, bg)
end
-- Either wait for the user to choose a route, or go away from the
-- station transponder.
local routeChosen = false
parallel.waitForAny( parallel.waitForAny(
function () function ()
while true do while true do
local event, button, x, y = os.pullEvent("mouse_click") local event, button, x, y = os.pullEvent("mouse_click")
if button == 1 then if button == 1 then
if x >= W-3 and y == 1 then if x >= W-3 and y == 1 then
break return
elseif y > 1 and y - 1 <= #routes then elseif y > 1 and y - 1 <= #stationIds then
local selectedRoute = routes[y-1] destination = stationIds[y-1]
os.queueEvent("rail_route_selected", selectedRoute)
routeChosen = true
return return
end end
end end
@ -151,8 +176,29 @@ local function handleNearbyStation()
end, end,
function () waitForNoStation(stationData.name) end function () waitForNoStation(stationData.name) end
) )
-- Quit our main loop if the user has chosen a route. if destination ~= nil then
if routeChosen then return end -- Fetch the whole route.
modem.transmit(SERVER_CHANNEL, MY_CHANNEL, {command = "ROUTE", startNode = stationData.name, endNode = destination})
local routeResponse = waitForModemMessage(SERVER_CHANNEL, 3)
if routeResponse and routeResponse.msg.success then
local routeEdgeIds = {}
for _, segment in pairs(routeResponse.msg.route) do
if segment.via then
table.insert(routeEdgeIds, segment.via)
end
end
os.queueEvent("rail_route_selected", {path = routeEdgeIds, destination = destination})
return
elseif routeResponse and routeResponse.msg.error then
drawErrorPage("Failed to get route: "..routeResponse.msg.error)
else
drawErrorPage("Failed to get route. Please contact an administrator if the issue persists.")
end
end
elseif response and response.msg.error then
drawErrorPage(response.msg.error)
else
drawErrorPage("Could not get a list of stations. Please contact an administrator if the issue persists.\n"..textutils.serialize(response, {compact=true}))
end end
end end
end end
@ -164,7 +210,7 @@ local function waitForRouteSelection()
handleNearbyStation handleNearbyStation
) )
local event, route = os.pullEvent("rail_route_selected") local event, route = os.pullEvent("rail_route_selected")
if event and type(route) == "table" then if event and route then
return route return route
end end
end end
@ -178,10 +224,7 @@ if #args > 1 then
for _, branch in pairs(route) do for _, branch in pairs(route) do
print(" "..branch) print(" "..branch)
end end
parallel.waitForAny( broadcastRoute(route)
function() broadcastRoute(route) end,
function() waitForStation(route[#route]) end
)
return return
end end
@ -203,7 +246,7 @@ while true do
parallel.waitForAny( parallel.waitForAny(
function() broadcastRoute(route.path) end, function() broadcastRoute(route.path) end,
function() waitForStation(route.path[#route.path]) end, function() waitForStation(route.destination) end,
function() -- Listen for user clicks on the "Quit" button. function() -- Listen for user clicks on the "Quit" button.
while true do while true do
local event, button, x, y = os.pullEvent("mouse_click") local event, button, x, y = os.pullEvent("mouse_click")