-- --- CONFIGURATION & STATE --- local mobs = {"Zombie", "Skeleton", "Spider", "Creeper", "Enderman", "Blaze", "Witch"} local state = { currentMenu = "main", power = false, spawnerActive = false, selectedMob = "Select Spawner" -- Corrected default text } -- Get monitor/screen dimensions dynamically local termWidth, termHeight = term.getSize() -- --- DRAWING UTILITIES --- local function clearScreen() term.setBackgroundColor(colors.black) term.clear() end local function drawRect(x, y, width, height, color) term.setBackgroundColor(color) for i = 0, height - 1 do term.setCursorPos(x, y + i) term.write(string.rep(" ", width)) end end local function drawText(x, y, text, bg, fg) term.setBackgroundColor(bg) term.setTextColor(fg) term.setCursorPos(x, y) term.write(text) end -- --- DRAW TOGGLE SWITCH --- local function drawToggle(x, y, isOn) drawRect(x, y, 5, 1, colors.gray) if isOn then drawRect(x + 3, y, 2, 1, colors.green) drawText(x + 1, y, "ON", colors.gray, colors.white) else drawRect(x, y, 2, 1, colors.red) drawText(x + 2, y, "OFF", colors.gray, colors.white) end end -- --- PERFECT CENTERING MATH --- -- Extra wide 32-block gray button background boxes local btnWidth = 32 local btnX = math.floor((termWidth - btnWidth) / 2) + 1 -- Width for alignment of the switch labels local contentWidth = 22 local contentX = math.floor((termWidth - contentWidth) / 2) + 1 -- --- SCREEN RENDERERS --- local function drawMainMenu() clearScreen() -- Centered Title Banner drawRect(1, 1, termWidth, 3, colors.blue) local titleText = "SPAWNER GRID" local titleX = math.floor((termWidth - #titleText) / 2) + 1 drawText(titleX, 2, titleText, colors.blue, colors.white) -- Power Section (Row 5) - Centered drawText(contentX, 5, "Power System:", colors.black, colors.white) drawToggle(contentX + 17, 5, state.power) -- Pull Spawner Button (Row 8) - Widened & Centered drawRect(btnX, 8, btnWidth, 3, colors.lightGray) local txtPull = " [ PULL SPAWNER ] " local txtPullX = btnX + math.floor((btnWidth - #txtPull) / 2) drawText(txtPullX, 9, txtPull, colors.lightGray, colors.black) -- Selected Mob Display (Row 12) - Centered local activeText = "Active Mob: " .. state.selectedMob local activeX = math.floor((termWidth - #activeText) / 2) + 1 drawText(activeX, 12, activeText, colors.black, colors.yellow) -- Spawner Active Switch (Row 14) - Centered drawText(contentX, 14, "Spawner Status:", colors.black, colors.white) drawToggle(contentX + 17, 14, state.spawnerActive) -- Put Spawner Away Button (Row 17) - Widened & Centered drawRect(btnX, 17, btnWidth, 3, colors.lightGray) local txtPut = " [ PUT SPAWNER AWAY ] " local txtPutX = btnX + math.floor((btnWidth - #txtPut) / 2) drawText(txtPutX, 18, txtPut, colors.lightGray, colors.black) end local function drawMobMenu() clearScreen() -- Centered Title drawRect(1, 1, termWidth, 3, colors.purple) local mobTitle = "SELECT A MONSTER" local mobTitleX = math.floor((termWidth - #mobTitle) / 2) + 1 drawText(mobTitleX, 2, mobTitle, colors.purple, colors.white) -- List of Mobs - Centered boxes local listWidth = 26 local listX = math.floor((termWidth - listWidth) / 2) + 1 for i, mob in ipairs(mobs) do local yPos = 4 + i drawRect(listX, yPos, listWidth, 1, colors.gray) -- Center text inside the row box local mobTxtX = listX + math.floor((listWidth - #mob) / 2) drawText(mobTxtX, yPos, mob, colors.gray, colors.white) end -- Back Button - Bottom center local backWidth = 12 local backX = math.floor((termWidth - backWidth) / 2) + 1 drawRect(backX, 17, backWidth, 3, colors.red) drawText(backX + 4, 18, "BACK", colors.red, colors.white) end local function render() if state.currentMenu == "main" then drawMainMenu() else drawMobMenu() end end -- --- INPUT HANDLING --- local function handleMainClick(x, y) -- Power Toggle Click Detection if x >= (contentX + 17) and x <= (contentX + 21) and y == 5 then state.power = not state.power return true end -- Pull Spawner Button Click Detection if x >= btnX and x <= (btnX + btnWidth - 1) and y >= 8 and y <= 10 then state.currentMenu = "mobs" return true end -- Spawner Status Toggle Click Detection if x >= (contentX + 17) and x <= (contentX + 21) and y == 14 then state.spawnerActive = not state.spawnerActive return true end -- Put Spawner Away Button Click Detection if x >= btnX and x <= (btnX + btnWidth - 1) and y >= 17 and y <= 19 then state.selectedMob = "Select Spawner" -- Resets to your default label state.spawnerActive = false return true end return false end local function handleMobClick(x, y) -- Back Button Click Detection local backWidth = 12 local backX = math.floor((termWidth - backWidth) / 2) + 1 if x >= backX and x <= (backX + backWidth - 1) and y >= 17 and y <= 19 then state.currentMenu = "main" return true end -- Mob Selection List Click Detection local listWidth = 26 local listX = math.floor((termWidth - listWidth) / 2) + 1 for i, mob in ipairs(mobs) do local yPos = 4 + i if x >= listX and x <= (listX + listWidth - 1) and y == yPos then state.selectedMob = mob state.currentMenu = "main" return true end end return false end -- --- MAIN PROGRAM LOOP --- render() while true do -- Works for both computer screen clicks and peripheral monitor clicks local event, side, x, y = os.pullEvent() if event == "mouse_click" or event == "monitor_touch" then local clicked = false if state.currentMenu == "main" then clicked = handleMainClick(x, y) elseif state.currentMenu == "mobs" then clicked = handleMobClick(x, y) end if clicked then render() end end end