Added iris detection

This commit is contained in:
2025-12-29 00:00:20 -05:00
parent 91c7cc2113
commit bda721b2de
2 changed files with 75 additions and 841 deletions

View File

@ -29,6 +29,7 @@ local mon = peripheral.find("monitor")
local gate = peripheral.find("advanced_crystal_interface")
or peripheral.find("crystal_interface")
or peripheral.find("basic_interface")
local transceiver = peripheral.find("transceiver")
if gate == nil then
error("Stargate interface not found! Please connect an interface.")
@ -38,6 +39,10 @@ if mon == nil then
error("Monitor not found! Please connect a monitor.")
end
if transceiver == nil then
print("WARNING: No transceiver found. Remote iris detection disabled.")
end
-- Check iris availability
if gate.getIris() == nil then
print("Config has Iris enabled, but there is no iris! Disabling Iris")
@ -123,6 +128,42 @@ local function Paratimeout()
return 2
end
local function MonitorRemoteIris()
-- Continuously monitor remote iris state while connected
while gate.isStargateConnected() do
sleep(2) -- Check every 2 seconds
if transceiver then
local remoteIrisState = transceiver.checkConnectedShielding()
if remoteIrisState and remoteIrisState > 0 then
-- Remote iris closed or closing
if remoteIrisState == 100 then
utils.log("ALERT: Remote iris fully closed during connection!")
else
utils.log("ALERT: Remote iris closing: " .. remoteIrisState .. "%")
end
mon.setBackgroundColor(colors.red)
mon.clear()
mon.setTextScale(1)
mon.setCursorPos(6, 5)
mon.write("REMOTE IRIS")
mon.setCursorPos(8, 7)
if remoteIrisState == 100 then
mon.write("CLOSED!")
else
mon.write(remoteIrisState .. "% CLOSED")
end
mon.setCursorPos(3, 10)
mon.write("Connection unsafe")
display.drawIrisStatus()
end
end
end
return 3 -- Return unique value to indicate iris monitoring ended
end
---------------------------------------------
-- INCOMING WORMHOLE HANDLER
---------------------------------------------
@ -359,12 +400,6 @@ end
local function handleOutgoingDial()
totalstate = true
local PDO = 0
-- parallel.waitForAny runs functions simultaneously and returns which finished first
-- Here we're waiting for either:
-- 1 = selectCategory (user selected a gate to dial)
-- 2 = Paratimeout (5 minutes passed with no selection)
-- This prevents the gate from staying on the selection screen forever
PDO = parallel.waitForAny(selectCategory, Paratimeout)
if (PDO == 1) and totalstate == true then
@ -372,7 +407,38 @@ local function handleOutgoingDial()
os.pullEvent("stargate_outgoing_wormhole")
-- Check if remote iris is closed using transceiver
local remoteIrisState = nil
if transceiver then
remoteIrisState = transceiver.checkConnectedShielding()
end
if remoteIrisState and remoteIrisState > 0 then
-- Remote iris is closed (partially or fully)
if remoteIrisState == 100 then
utils.log("WARNING: Remote iris is fully closed!")
else
utils.log("WARNING: Remote iris is " .. remoteIrisState .. "% closed!")
end
mon.setBackgroundColor(colors.red)
mon.clear()
mon.setTextScale(1)
mon.setCursorPos(6, 5)
mon.write("REMOTE IRIS")
mon.setCursorPos(8, 7)
if remoteIrisState == 100 then
mon.write("CLOSED!")
else
mon.write(remoteIrisState .. "% CLOSED")
end
mon.setCursorPos(3, 10)
mon.write("Connection unsafe")
display.drawIrisStatus()
else
-- Remote iris is open or no iris present
display.showConnected(destAddressname, destAddress)
end
if (gate.isStargateConnected() == true) then
-- parallel.waitForAny runs functions at the same time, returns which finished first
@ -380,8 +446,9 @@ local function handleOutgoingDial()
-- DisconnectCheck = gate disconnects naturally (timeout or remote disconnect)
-- ParaDisconnect = user manually clicks screen to disconnect
-- Paratimeout = safety timeout (5 minutes)
-- MonitorRemoteIris = continuously checks remote iris state
-- Whichever happens first ends the connection
PDO = parallel.waitForAny(DisconnectCheck, ParaDisconnect, Paratimeout)
PDO = parallel.waitForAny(DisconnectCheck, ParaDisconnect, Paratimeout, MonitorRemoteIris)
dialing = false
end
end
@ -398,13 +465,6 @@ end
local function mainMenu()
while true do
display.showMainMenu()
-- parallel.waitForAny runs multiple functions simultaneously, returns which completes first
-- The main menu waits for any of these events:
-- 1 = GetClick (user touched the monitor anywhere - assumes they want to dial out)
-- 2 = GetActivation (incoming wormhole detected with address)
-- Note: We don't wait for CheveronActivation here because it fires at the same time
-- as the incoming wormhole event, causing a race condition where we might miss the address
local answer = parallel.waitForAny(GetClick, GetActivation)
if (answer == 1) then

View File

@ -1,826 +0,0 @@
-- Gate dialing speed (seconds between chevrons for non-Milky Way gates)
local gatespeed = 0.5
local manualDial = true
local canAccessHazardGates = true
local irisEnabled = true
local autoCloseIrisOnIncoming = true
local irisCloseDelay = 0.1 -- seconds before closing iris on incoming
local autoOpenIrisAfterDisconnect = true
local whitelist = {
{ "Glaive", { 33, 6, 10, 24, 1, 30, 3, 17, 0 } },
{ "Moon", { 32, 33, 8, 7, 25, 21, 14, 35, 0 } },
{ "Caldoric", { 18, 2, 24, 16, 8, 19, 4, 29, 0 } },
{ "Trading Hall", { 16, 19, 6, 18, 35, 27, 9, 8, 0 } }
}
local blacklist = {
-- {"DangerGate", {1,2,3,4,5,6,0}},
}
local enableLogging = true
local logFile = "stargate.log"
---------------------------------------------
-- ADDRESS BOOK
---------------------------------------------
-- Main Gates (7-chevron addresses for common destinations)
local MainGates = {
{ "OVERWORLD", { 27, 25, 4, 35, 10, 28, 0 } },
{ "Nether", { 27, 23, 4, 34, 12, 28, 0 } },
{ "End", { 13, 24, 2, 19, 3, 30, 0 } },
{ "Abydos", { 26, 6, 14, 31, 11, 29, 0 } },
{ "Chulak", { 8, 1, 22, 14, 36, 19, 0 } }
}
-- Player Gates (typically 9-chevron addresses)
local playerGates = {
{ "Glaive", { 33, 6, 10, 24, 1, 30, 3, 17, 0 } },
{ "Moon", { 32, 33, 8, 7, 25, 21, 14, 35, 0 } },
{ "Caldoric", { 18, 2, 24, 16, 8, 19, 4, 29, 0 } },
{ "Trading Hall", { 16, 19, 6, 18, 35, 27, 9, 8, 0 } }
}
-- Hazard Gates (dangerous destinations)
local hazardGates = {
-- Add hazardous gate addresses here
}
---------------------------------------------
-- INITIALIZATION
---------------------------------------------
-- Find and initialize peripherals
local mon = peripheral.find("monitor")
local gate = peripheral.find("advanced_crystal_interface")
if gate == nil then
error("Stargate interface not found! Please connect an interface.")
end
if mon == nil then
error("Monitor not found! Please connect a monitor.")
end
-- Ensure gate starts disconnected
gate.disconnectStargate()
-- Ensure iris starts open (unless there's a threat)
if irisEnabled then
gate.openIris()
end
---------------------------------------------
-- GLOBAL VARIABLES
---------------------------------------------
-- Outgoing connection state
local destAddress = {}
local buttonXY = {}
local computerAddresses = {}
local computerNames = {}
local destAddressname = ""
local x, y = 0, 0
local selx, sely = 0, 0
local dialing = false
local totalstate = nil
-- Incoming connection state
local incomingAddress = {}
local incomingEntityType = ""
local incomingEntityName = ""
-- Menu state
local disconnect = false
---------------------------------------------
-- UTILITY FUNCTIONS
---------------------------------------------
local function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[deepcopy(orig_key)] = deepcopy(orig_value)
end
setmetatable(copy, deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
local function log(message)
if enableLogging then
local timestamp = os.date("%Y-%m-%d %H:%M:%S")
local logEntry = "[" .. timestamp .. "]\n" .. message
-- local logEntry = message
-- Write to console
print(logEntry)
-- Write to file
local file = fs.open(logFile, "a")
if file then
file.writeLine(logEntry)
file.close()
end
end
end
local function addressToTable(address)
if type(address) == "table" then
return address
end
return {}
end
local function compareAddresses(addr1, addr2)
addr1 = gate.addressToString(addr1)
addr2 = gate.addressToString(addr2)
return addr1 == addr2
end
local function isAddressInList(address, list)
for _, entry in ipairs(list) do
local listAddr = entry[2]
tmp = deepcopy(listAddr)
table.remove(tmp)
if compareAddresses(address, tmp) then
return true, entry[1]
end
end
return false, nil
end
local function isAddressAllowed(address)
-- Check blacklist first
local isBlacklisted, blackName = isAddressInList(address, blacklist)
if isBlacklisted then
return false, "Blacklisted: " .. blackName
end
-- If whitelist is not empty, check whitelist
if #whitelist > 0 then
local isWhitelisted, whiteName = isAddressInList(address, whitelist)
if isWhitelisted then
return true, "Whitelisted: " .. whiteName
else
return false, "Not on whitelist"
end
end
-- If no whitelist, allow all non-blacklisted
return true, "Allowed"
end
---------------------------------------------
-- IRIS CONTROL FUNCTIONS
---------------------------------------------
local function closeIris()
if irisEnabled then
gate.closeIris()
log("Iris closed")
return true
end
return false
end
local function openIris()
if irisEnabled then
gate.openIris()
log("Iris opened")
return true
end
return false
end
local function getIrisState()
if irisEnabled then
if gate.getIrisProgressPercentage() == 0 then
return "OPEN"
else
if gate.getIrisProgressPercentage() == 100 then
return "CLOSED"
else
return "MOVING"
end
end
end
return "NO IRIS"
end
---------------------------------------------
-- DISPLAY FUNCTIONS
---------------------------------------------
local function screenWrite(list, fcount, fy)
local internaladdress = {}
for i = 1, #list do
local x1, x2 = 0, 0
if fcount == 0 then
x = 2
fcount = 1
elseif fcount == 1 then
x = 11
fcount = 2
else
x = 20
fcount = 0
fy = fy + 2
end
mon.setCursorPos(x, fy)
mon.write(list[i][1])
x1 = x
x2 = x + 7
table.insert(buttonXY, { x1, x2, fy })
table.insert(computerNames, list[i][1])
-- list[i][2] is now the address table directly
table.insert(computerAddresses, list[i][2])
internaladdress = {}
end
local oldterm = term.redirect(mon)
paintutils.drawFilledBox(23, 17, 28, 19, colors.red)
mon.setCursorPos(24, 18)
mon.write("Back")
term.redirect(oldterm)
return fcount, fy
end
local function drawIrisStatus()
mon.setCursorPos(1, 19)
mon.setBackgroundColor(colors.black)
local irisState = getIrisState()
if irisState == "OPEN" then
mon.setTextColor(colors.green)
elseif irisState == "CLOSED" then
mon.setTextColor(colors.red)
else
mon.setTextColor(colors.gray)
end
mon.write("IRIS: " .. irisState .. " ")
mon.setTextColor(colors.white)
if irisState == "MOVING" then
sleep(0.1)
drawIrisStatus()
end
end
local function SelectDial()
local x1, x2 = 0, 0
local count = 0
y = 2
mon.setBackgroundColor(colors.black)
mon.clear()
if #MainGates ~= 0 then
mon.setBackgroundColor(colors.purple)
count, y = screenWrite(MainGates, count, y)
end
if #playerGates ~= 0 then
mon.setBackgroundColor(colors.green)
count, y = screenWrite(playerGates, count, y)
end
if (#hazardGates ~= 0) and (canAccessHazardGates == true) then
mon.setBackgroundColor(colors.red)
count, y = screenWrite(hazardGates, count, y)
end
drawIrisStatus()
return 1
end
local function selectionTabs()
mon.setBackgroundColor(colors.black)
mon.clear()
local oldterm = term.redirect(mon)
if #MainGates ~= 0 then
paintutils.drawFilledBox(2, 2, 13, 6, colors.purple)
mon.setCursorPos(4, 4)
mon.setBackgroundColor(colors.purple)
mon.write("Main Gates")
end
if #playerGates ~= 0 then
paintutils.drawFilledBox(16, 2, 27, 6, colors.green)
mon.setCursorPos(18, 4)
mon.setBackgroundColor(colors.green)
mon.write("Player")
mon.setCursorPos(18, 5)
mon.write("Base gates")
end
if (#hazardGates ~= 0) and (canAccessHazardGates == true) then
paintutils.drawFilledBox(2, 8, 13, 12, colors.red)
mon.setCursorPos(4, 9)
mon.setBackgroundColor(colors.red)
mon.write("Hazard")
mon.setCursorPos(4, 11)
mon.write("gates")
end
paintutils.drawFilledBox(23, 17, 28, 19, colors.red)
mon.setCursorPos(24, 18)
mon.write("Back")
drawIrisStatus()
term.redirect(oldterm)
end
---------------------------------------------
-- EVENT HANDLING FUNCTIONS
---------------------------------------------
local function GetClick()
mon.setTextScale(1)
local event, _, xPos, yPos = os.pullEvent("monitor_touch")
return xPos, yPos
end
local function GetActivation()
_, _, incomingAddress = os.pullEvent("stargate_incoming_wormhole")
return 1
end
local function CheveronActivation()
local event, _, _, _, incomingBool = os.pullEvent("stargate_chevron_engaged")
if incomingBool == true then
log("External dial detected")
else
log("Internal dial detected")
end
return 1
end
local function ParaDisconnect()
local dx, dy = 0, 0
_, _, dx, dy = os.pullEvent("monitor_touch")
if (dx ~= 0) and (dy ~= 0) then
gate.disconnectStargate()
redstone.setOutput("top", false)
log("Manual disconnect triggered")
end
return 1
end
local function EntityRead()
sleep(0.1)
_, _, incomingEntityType, incomingEntityName, _ = os.pullEvent("stargate_reconstructing_entity")
log("Entity reconstructed: " .. incomingEntityName .. " (" .. incomingEntityType .. ")")
return 1
end
local function DisconnectCheck()
local _, _, disCode = os.pullEvent("stargate_disconnected")
redstone.setOutput("top", false)
log("Stargate disconnected (code: " .. tostring(disCode) .. ")")
-- Auto-open iris after disconnect
if autoOpenIrisAfterDisconnect then
openIris()
end
return 2
end
---------------------------------------------
-- INCOMING WORMHOLE HANDLER
---------------------------------------------
local function PRIMARYwormholeIncoming()
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setBackgroundColor(colors.red)
mon.setTextScale(1)
mon.setCursorPos(9, 4)
mon.write("INCOMING")
-- Convert address to table if needed
incomingAddress = addressToTable(incomingAddress)
-- Check security
local allowed, reason = isAddressAllowed(incomingAddress)
-- Try to get address string
local addressString = gate.addressToString(incomingAddress) or "Unknown"
log("Incoming wormhole from: " .. addressString .. " " .. reason)
mon.setBackgroundColor(colors.black)
mon.clear()
if allowed then
mon.setBackgroundColor(colors.green)
mon.setTextScale(1)
mon.setCursorPos(1, 2)
mon.write("INCOMING - AUTHORIZED")
-- Open iris for authorized connections
if autoCloseIrisOnIncoming then
sleep(irisCloseDelay)
openIris()
end
else
mon.setBackgroundColor(colors.red)
mon.setTextScale(1)
mon.setCursorPos(1, 2)
mon.write("INCOMING - UNAUTHORIZED")
mon.setCursorPos(1, 4)
mon.write(reason)
-- Close iris for unauthorized connections
if autoCloseIrisOnIncoming then
sleep(irisCloseDelay)
closeIris()
end
end
mon.setCursorPos(1, 6)
mon.setBackgroundColor(colors.black)
mon.write("Address:")
mon.setCursorPos(1, 7)
mon.write(addressString)
-- Monitor for incoming entities
disconnect = false
while (disconnect == false) do
-- parallel.waitForAny runs multiple functions at the same time and returns which one finished first
-- Here we're watching for 3 things simultaneously:
-- 1 = EntityRead (someone/something came through the gate)
-- 2 = DisconnectCheck (gate disconnected on its own)
-- ParaDisconnect (user clicked screen to manually disconnect)
-- Whichever happens first, that function returns and we handle it
local incomingcheck = parallel.waitForAny(EntityRead, DisconnectCheck, ParaDisconnect)
if (incomingcheck == 1) then
mon.setTextScale(1)
mon.setCursorPos(1, 10)
mon.write("Type: " .. incomingEntityType)
mon.setCursorPos(1, 12)
mon.write("Name: " .. incomingEntityName)
-- Check if entity should be blocked
if not allowed then
mon.setCursorPos(1, 14)
mon.setTextColor(colors.red)
mon.write("IRIS IMPACT!")
mon.setTextColor(colors.white)
end
incomingEntityType = ""
incomingEntityName = ""
else
disconnect = true
end
end
disconnect = false
end
---------------------------------------------
-- DIALING FUNCTIONS
---------------------------------------------
local function Dial(address)
log("Dialing: " .. gate.addressToString(address))
local gateType = gate.getStargateType()
-- Manual Milky Way dialing with ring rotation
if gateType == "sgjourney:milky_way_stargate" and manualDial == true then
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setBackgroundColor(colors.red)
mon.setTextScale(2)
mon.setCursorPos(2, 3)
mon.write("DIALING GATE")
local addressLength = #address
if addressLength == 8 then
gate.setChevronConfiguration({ 1, 2, 3, 4, 6, 7, 8, 5 })
elseif addressLength == 9 then
gate.setChevronConfiguration({ 1, 2, 3, 4, 5, 6, 7, 8 })
end
local start = gate.getChevronsEngaged() + 1
for chevron = start, addressLength, 1 do
local symbol = address[chevron]
if chevron % 2 == 0 then
gate.rotateClockwise(symbol)
else
gate.rotateAntiClockwise(symbol)
end
while (not gate.isCurrentSymbol(symbol)) do
sleep(0)
end
gate.openChevron()
sleep(1)
gate.closeChevron()
sleep(0.5)
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setBackgroundColor(colors.red)
mon.setTextScale(2)
mon.setCursorPos(2, 3)
mon.write("DIALING GATE")
mon.setCursorPos(4, 5)
mon.write("CHEVERON")
mon.setCursorPos(7, 7)
mon.setBackgroundColor(colors.black)
mon.write(chevron)
mon.setBackgroundColor(colors.red)
if symbol ~= 0 then
mon.setCursorPos(4, 9)
mon.write("ENGAGED")
else
mon.setCursorPos(5, 9)
mon.setBackgroundColor(colors.green)
mon.write("LOCKED")
end
end
else
-- Automatic dialing for other gate types
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setBackgroundColor(colors.red)
mon.setTextScale(2)
mon.setCursorPos(2, 3)
mon.write("DIALING GATE")
if gateType ~= "sgjourney:universe_stargate" then
local addressLength = #address
if addressLength == 8 then
gate.setChevronConfiguration({ 1, 2, 3, 4, 6, 7, 8, 5 })
elseif addressLength == 9 then
gate.setChevronConfiguration({ 1, 2, 3, 4, 5, 6, 7, 8 })
end
end
local start = gate.getChevronsEngaged() + 1
for chevron = start, #address, 1 do
local symbol = address[chevron]
gate.engageSymbol(symbol)
sleep(gatespeed)
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setBackgroundColor(colors.red)
mon.setTextScale(2)
mon.setCursorPos(2, 3)
mon.write("DIALING GATE")
mon.setCursorPos(4, 5)
mon.write("CHEVERON")
mon.setCursorPos(7, 7)
mon.setBackgroundColor(colors.black)
mon.write(chevron)
mon.setBackgroundColor(colors.red)
if (symbol) ~= 0 then
mon.setCursorPos(4, 9)
mon.write("ENGAGED")
if (gateType == "sgjourney:universe_stargate") or (gateType == "sgjourney:pegasus_stargate") then
os.pullEvent("stargate_chevron_engaged")
end
else
if gateType == "sgjourney:universe_stargate" then
os.pullEvent("stargate_chevron_engaged")
redstone.setOutput("top", true)
elseif (gateType == "sgjourney:pegasus_stargate") then
os.pullEvent("stargate_chevron_engaged")
end
mon.setCursorPos(5, 9)
mon.setBackgroundColor(colors.green)
mon.write("LOCKED")
end
end
address = nil
end
end
local function ParaDial()
local selecting = true
while dialing == false and selecting == true do
selx, sely = GetClick()
for i = 1, #buttonXY do
if (sely == buttonXY[i][3]) and ((selx >= buttonXY[i][1]) and (selx <= buttonXY[i][2])) then
Dial(computerAddresses[i])
destAddressname = computerNames[i]
destAddress = computerAddresses[i]
dialing = true
sely = 0
selx = 0
elseif sely >= 17 and selx >= 23 then
selecting = false
sely = 0
selx = 0
end
end
end
buttonXY = {}
computerAddresses = {}
computerNames = {}
return dialing
end
local function tabSelector()
local state = true
while state == true do
mon.setBackgroundColor(colors.black)
mon.clear()
selectionTabs()
local tabx, taby = GetClick()
y = 2
local count = 0
if (taby >= 2) and (taby <= 6) and ((tabx >= 2) and (tabx <= 13)) then
if #MainGates ~= 0 then
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setBackgroundColor(colors.purple)
count, y = screenWrite(MainGates, count, y)
local returnstate = ParaDial()
if returnstate == true then
state = false
end
computerAddresses = {}
computerNames = {}
else
mon.setCursorPos(9, 7)
mon.write("no gates available")
sleep(5)
end
elseif (taby >= 2) and (taby <= 6) and ((tabx >= 16) and (tabx <= 27)) then
if #playerGates ~= 0 then
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setBackgroundColor(colors.green)
count, y = screenWrite(playerGates, count, y)
local returnstate = ParaDial()
if returnstate == true then
state = false
end
computerAddresses = {}
computerNames = {}
else
mon.setCursorPos(9, 7)
mon.write("no gates available")
sleep(5)
end
elseif (((taby >= 8) and (taby <= 12)) and ((tabx >= 2) and (tabx <= 13))) and (canAccessHazardGates == true) then
if (#hazardGates ~= 0) and (canAccessHazardGates == true) then
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setBackgroundColor(colors.red)
count, y = screenWrite(hazardGates, count, y)
local returnstate = ParaDial()
if returnstate == true then
state = false
end
computerAddresses = {}
computerNames = {}
else
mon.setCursorPos(9, 7)
mon.write("no gates available")
sleep(5)
end
elseif (taby >= 17) and (tabx >= 23) then
state = false
totalstate = false
end
end
return 1
end
local function Paratimeout()
sleep(300)
return 2
end
local function DialText()
mon.setBackgroundColor(colors.green)
mon.clear()
mon.setTextScale(1)
mon.setCursorPos(6, 5)
mon.write(destAddressname)
mon.setCursorPos(3, 10)
for i = 1, #destAddress do
mon.write(destAddress[i])
mon.write(" ")
end
drawIrisStatus()
destAddress = {}
destAddressname = ""
end
local function PRIMARYDialingOut()
totalstate = true
local PDO = 0
PDO = parallel.waitForAny(tabSelector, Paratimeout)
if (PDO == 1) and totalstate == true then
sleep(1)
os.pullEvent("stargate_outgoing_wormhole")
DialText()
if (gate.isStargateConnected() == true) then
PDO = parallel.waitForAny(DisconnectCheck, ParaDisconnect, Paratimeout)
dialing = false
end
end
computerAddresses = {}
computerNames = {}
end
---------------------------------------------
-- MAIN MENU
---------------------------------------------
function Menu()
while true do
mon.setTextScale(1)
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setCursorPos(9, 1)
mon.setBackgroundColor(colors.red)
mon.write("press to start")
drawIrisStatus()
local answer = parallel.waitForAny(GetClick, GetActivation)
if (answer == 1) then
PRIMARYDialingOut()
else
PRIMARYwormholeIncoming()
end
end
end
---------------------------------------------
-- STARTUP
---------------------------------------------
if gate.getIris() == nil then
log("Config has Iris enabled, but there is no iris! Disabling Iris")
irisEnabled = false
end
-- log("=== Stargate Control System Starting ===")
-- log("Gate Type: " .. gate.getStargateType())
-- log("Iris Available: " .. tostring(irisEnabled))
-- log("Configuration: Manual Dial=" .. tostring(manualDial) .. ", Auto Iris=" .. tostring(autoCloseIrisOnIncoming))
-- Start the main menu
Menu()