-- Load necessary APIs
os.loadAPI("/button")
-- Configuration
local config = {
boxColor = colors.blue,
buttonsPerRow = 4,
buttonWidth = 16,
buttonHeight = 3,
textScale = 0.5,
infoBG = colors.red,
updateTime = 60
}
-- ########### ToDo
-- set different portal color after portal switch
-- Debug data
local debug = false
local debugArray = {}
local entries = 200
-- Populate debugArray
for i = 1, entries do
table.insert(debugArray, {key = "Portal" .. i, public = true})
end
-- Function to ensure the presence of required peripherals (monitor and teleporter).
function checkPeripheral(name, errorMessage)
local peripheral = peripheral.find(name)
if not peripheral then
error(errorMessage)
end
return peripheral
end
-- Retrieve peripherals
local mon = checkPeripheral("monitor", "Monitor peripheral not found.")
local tp = checkPeripheral("teleporter", "Teleporter peripheral not found.")
lastActiveButton = nil
-- Determine whether to use debug data or actual teleporter frequencies.
local inputArray = debug and debugArray or tp.getFrequencies()
-- Function to display a countdown timer on the monitor when the monitorsize is incorrect.
function showTimer(seconds, centerX, centerY)
while seconds >= 0 do
mon.setCursorPos(centerX, centerY)
mon.setTextColor(colors.white)
mon.setBackgroundColor(colors.black)
mon.write("Timer: " .. tostring(seconds) .. "s remaining ")
os.sleep(1)
seconds = seconds - 1
end
os.reboot()
end
-- Function to check and handle monitor size discrepancies.
function checkMonitorSize()
local w, h = mon.getSize()
if w ~= 79 or h ~= 38 then
mon.clear()
local centerX = math.floor((w - #"ERROR: Monitor size is not correct.") / 2)
local centerY = math.floor(h / 2)
mon.setCursorPos(centerX, centerY)
mon.setTextColor(colors.red)
mon.write("ERROR: Monitor size is not correct.")
centerY = centerY + 1
mon.setCursorPos(centerX, centerY)
mon.write("Required size: 3 Heigh / 4 Width")
centerY = centerY + 1
mon.setCursorPos(centerX, centerY)
mon.write("Please adjust the monitor size and restart.")
showTimer(10, centerX, centerY + 2)
error("Monitor size is not correct.")
end
end
-- Set monitor text properties and initialize variables for pagination.
mon.setTextScale(config.textScale)
mon.setBackgroundColor(colors.black)
currentPage = 1
maxButtons = 24
totalPages = math.ceil(#inputArray / maxButtons)
-- Function to set the frequency based on the button pressed.
local function setFrequency(freq)
if not debug then
tp.setFrequency(freq)
end
button.toggleButton(freq)
end
-- Function to dynamically fill the button table based on the current page.
function fillTable()
local w, h = mon.getSize()
local spacingX = 2
local spacingY = 1
local maxButtons = maxButtons
local startIndex = (currentPage - 1) * maxButtons + 1
local endIndex = math.min(startIndex + maxButtons - 1, #inputArray)
local totalRows = math.ceil(maxButtons / config.buttonsPerRow)
local totalWidth = config.buttonsPerRow * (config.buttonWidth + spacingX) - spacingX
local startX = math.floor((w - totalWidth) / 2) + 1
for i = startIndex, endIndex do
-- Calculate the position of the current button
local col = (i - 1) % config.buttonsPerRow
local row = math.floor((i - 1) / config.buttonsPerRow) % totalRows
local x = startX + col * (config.buttonWidth + spacingX)
local y = 9 + row * (config.buttonHeight + spacingY)
-- Place the button at the calculated position
local entry = inputArray[i]
button.setTable(entry.key, function() setFrequency(entry.key) end, x, x + config.buttonWidth - 1, y, y + config.buttonHeight - 1)
end
if currentPage > 1 then
button.setTable("Previous", prevPage, 2 , 22 , 35 , 37)
end
button.setTable("Refresh", refresh, 30 , 50 , 35 , 37)
if currentPage < totalPages then
button.setTable("Next" , nextPage, 58 , 78 , 35 , 37)
end
button.screen()
end
-- Function to display portal information.
function displayInfo()
mon.setCursorPos(10, 6)
mon.setBackgroundColor(config.infoBG)
mon.setTextColor(colors.white)
mon.write("Active Portal: Status: ")
end
-- Function to update portal information continuously.
local function updateInfo()
while true do
local afq = tp.getFrequency()
local sfq = tp.getStatus()
mon.setCursorPos(25,6)
mon.setBackgroundColor(config.infoBG)
mon.setTextColor(colors.white)
mon.write(string.format("%-25s", afq.key))
mon.setCursorPos(60,6)
mon.write(string.format("%-10s", sfq:sub(1, 1):upper() .. sfq:sub(2)))
mon.setBackgroundColor(colors.black)
os.sleep(0.25)
end
end
-- Function to initialize the main interface.
local function main()
button.clearTable()
checkMonitorSize()
fillTable()
button.drawButtonBoxes(config.boxColor)
button.drawBox(5, 5, 74, 7, config.infoBG)
button.drawBox(5, 6, 74, 6, config.infoBG)
button.heading(" Portal Control ", 2, config.infoBG)
displayInfo()
local activeFreq = tp.getFrequency()
if not debug then
button.toggleButton(activeFreq.key)
end
end
-- Functions to navigate to the next page of portals.
function nextPage()
currentPage = currentPage + 1
button.flash("Next")
main()
end
-- Functions to navigate to the previous page of portals.
function prevPage()
if currentPage > 1 then
currentPage = currentPage - 1
button.flash("Previous")
main()
end
end
-- Function to refresh the portal list.
function refresh()
button.flash("Refresh")
inputArray = debug and debugArray or tp.getFrequencies()
main()
end
-- Function to handle monitor touch events.
local function getClick()
event,side,x,y = os.pullEvent("monitor_touch")
button.checkxy(x,y)
end
-- Function to auto-refresh frequencies.
local function autoRefresh()
while true do
os.sleep(config.updateTime)
inputArray = debug and debugArray or tp.getFrequencies()
main()
end
end
-- Initialize the main interface.
main()
-- Continuously wait for monitor touch events or display portal information.
while true do
parallel.waitForAny(getClick, updateInfo, autoRefresh)
end
Comments