gelatine87 icon

MekanismPortal

gelatine87 | PRO | 07/22/24 10:33:05 PM UTC (Edited) | 0 ⭐ | 403 👁️ | Never ⏰ | [computercraft]
Lua |

6.63 KB

|

Gaming

|

0 👍

/

0 👎

-- 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