-- ARASAKA CORPORATE AD — CYBERPUNK EDITION -- Für ComputerCraft / CC: Tweaked (Minecraft) -- Funktioniert auf ALLEN Monitoren (auch schwarz-weiß) -- ========== KONFIGURATION ========== local LOGO_TEXT = "ARASAKA" local DISPLAY_DURATION = 25 -- Sekunden pro Seite local bottomRows = 8 -- Platz für Animation unten local TICK_INTERVAL = 0.3 -- Seiteninhalt local PAGES = { { id="infra", title="ARASAKA INFRASTRUCTURE", subtitle="SICHERHEIT. NETZWERK. ZUKUNFT.", body={ "\"Ihr Vertrauen ist unser Kapital.\"", "", "GLOBAL SERVICES:", "- Sichere Datenverbindungen", "- Logistiknetz & Corporate Hosting", "- Private Netze für Konzerne" }}, { id="express", title="ARASAKA EXPRESS", subtitle="DER ZUG DER ELITE", body={ "Schnell. Pünktlich. Unbestechlich.", "", "TARIFE:", "• Einzelreise: 500 Emeralds", "• Monatsabo: 3.000 Emeralds", "• VIP-Kabine: +1.000 Emeralds", "", "„Nur Arasaka bringt Sie lebend an.“" }}, { id="hotel", title="ARASAKA GRAND HOTEL", subtitle="LUXUS UNTER MAXIMALER SICHERHEIT", body={ "Ihr Rückzugsort in einer unsicheren Welt.", "24/7 bewacht, klimatisiert, Safe-Raum.", "", "PREISE (pro Nacht):", "• Standard: 800 Emeralds", "• Executive: 2.500 Emeralds", "• Präsidentensuite: 6.000 Emeralds", "", "„Schlafen Sie ruhig. Wir wachen.“" }}, { id="security", title="ARASAKA SECURITY", subtitle="IHRE UNSICHTBARE WAFFE", body={ "Erstklassige Teams für alle Bedrohungen.", "", "PAKETE:", "• Grundschutz (1 Bodyguard): 1.200 Emeralds", "• Elite-Eskorte (+Drohnen): 4.500 Emeralds", "• 24/7 Gebäudeüberwachung: 3.000 Emeralds", "• Notfall-Extraktion: 7.000 Emeralds", "", "„Gefahr erkannt. Gefahr eliminiert.“" }}, { id="elite", title="ARASAKA ELITE PAKET", subtitle="Sparpaket • Persönlicher Service", body={ "Kombinieren Sie Zug + Hotel + Security!", "Sparen Sie bis zu 20%.", "", "STARTPREIS: Ab 8.000 Emeralds", "- Persönlicher Berater", "- Zugang zum Exklusiv-Netzwerk", "", "Für VIPs, Diplomaten, Konzerngremien." }}, { id="contact", title="KONTAKT", subtitle="VERTRAUEN SIE ARASAKA", body={ "Hauptsitz: Arasaka Tower, Block 666", "Nether-Edge District", "", "Kontakt: /msg Arasaka_HQ (in-game)", "", "„Vertrauen Sie keinem anderen Konzern.", "Vertrauen Sie Arasaka.“" }} } -- ========== MONITOR SETUP ========== if not peripheral then error("ComputerCraft API 'peripheral' benötigt.") end local monitor = peripheral.find("monitor") or peripheral.find("advanced_monitor") if not monitor then error("Kein Monitor gefunden. An Computer anschließen!") end -- API-Optimierung local m = monitor local w, h = m.getSize() local setCursorPos = m.setCursorPos local setTextColor = m.setTextColor local setBackgroundColor = m.setBackgroundColor local write = m.write local clear = m.clear local isColor = m.isColor and m.isColor() -- Farben – sicher für alle Monitore local C = { bg = isColor and colors.black or colors.white, neon = isColor and colors.red or colors.black, neonAlt = isColor and (colors.orange or colors.yellow) or colors.black, cyan = isColor and colors.cyan or colors.black, white = isColor and colors.white or colors.black, dim = isColor and colors.gray or colors.lightGray, } -- Textskalierung if m.setTextScale then if w >= 80 or h >= 30 then m.setTextScale(0.5) elseif w >= 50 or h >= 20 then m.setTextScale(0.75) end end -- ========== HILFSFUNKTIONEN ========== local function clamp(v, a, b) return math.min(math.max(v, a), b) end local function fillRect(x, y, width, height, col) if width <= 0 or height <= 0 then return end setBackgroundColor(col) for dy = 0, height - 1 do local ry = y + dy if ry >= 1 and ry <= h then setCursorPos(x, ry) write((" "):rep(clamp(width, 0, w - x + 1))) end end end local function clearScreen() setBackgroundColor(C.bg) clear() end -- ========== LOGO (links) ========== local function drawLogo(offset) local leftW = clamp(math.floor(w * 0.22), 8, 16) fillRect(1, 1, leftW, h, C.bg) local letters = LOGO_TEXT local blockH = clamp(math.floor((h - 4) / #letters), 2, 5) local blockW = leftW - 2 for i = 1, #letters do local ch = letters:sub(i, i) local y = 3 + (i - 1) * (blockH + 1) + offset if y >= 1 and y + blockH <= h then -- Rahmen fillRect(2, y, blockW, 1, C.neon) fillRect(2, y + blockH - 1, blockW, 1, C.neon) fillRect(2, y + 1, 1, blockH - 2, C.neon) fillRect(2 + blockW - 1, y + 1, 1, blockH - 2, C.neon) -- Buchstabe setCursorPos(2 + math.floor(blockW / 2), y + math.floor(blockH / 2)) setBackgroundColor(C.bg) setTextColor(C.neon) write(ch) end end setTextColor(C.white) end -- ========== SEITENANZEIGE ========== local function drawPage(page, panelX, panelW) fillRect(panelX, 1, panelW, h, C.bg) -- Titel if h >= 2 then setCursorPos(panelX + 2, 2) setTextColor(C.neon) write((page.title or ""):sub(1, panelW - 4)) end -- Untertitel if h >= 3 then setCursorPos(panelX + 2, 3) setTextColor(C.cyan) write((page.subtitle or ""):sub(1, panelW - 4)) end -- Trennlinie if h >= 4 then setCursorPos(panelX + 2, 4) setTextColor(C.neon) write(("-"):rep(math.min(30, panelW - 4))) end -- Inhalt local y = 6 local maxY = h - bottomRows - 1 for _, line in ipairs(page.body) do if y > maxY then break end if y <= h then setCursorPos(panelX + 3, y) if line:find("Emeralds") then setTextColor(C.neonAlt) else setTextColor(C.white) end write(line:sub(1, panelW - 6)) end y = y + 1 end -- Footer if h >= 2 then setCursorPos(panelX + 2, h) setTextColor(C.dim) write(("[%s]"):format(page.id:upper())) end end -- ========== ANIMATIONEN ========== local animState = { bullets = {}, lastSpawn = 0 } -- ICE 3 Zug -- ICE 3 Zug (korrigiert & optimiert) local function drawICE3(panelX, panelW, x) -- Kompakter, sicherer ICE 3 (5 Zeilen, keine Tabs, keine Sonderzeichen) local train = { " _________________________________________________________", " /|####| #### #### #### #### #### |", " /_|___|____________________________________________________|_", " ( | o | (o) (o) (o) (o) (o) | )", " \\_|__/o)~~~~(o)~~~~(o)~~~~(o)~~~~(o)~~~~(o)~~~~(o)~~~~(o)/" } local blink = math.floor(os.clock() * 2) % 2 == 0 for dy, line in ipairs(train) do local ry = h - bottomRows + dy if ry >= 1 and ry <= h then for dx = 1, #line do local cx = panelX + x + dx - 1 if cx >= panelX and cx < panelX + panelW and cx >= 1 and cx <= w then local ch = line:sub(dx, dx) setCursorPos(cx, ry) -- Farbzuweisung if ch == "#" then setTextColor(C.neon) -- Roter Streifen elseif ch == "o" or ch == "O" then setTextColor(C.cyan) -- Räder elseif ch == "(" or ch == ")" or ch == "~" or ch == "_" or ch == "/" or ch == "\\" then setTextColor(C.dim) -- Struktur else setTextColor(C.white) -- Standard end setBackgroundColor(C.bg) write(ch) end end end end end -- Sicherheitsdrohnen local function drawSecurity(panelX, panelW) fillRect(panelX, h - bottomRows + 1, panelW, bottomRows, C.bg) -- Drohnen spawnen if os.clock() - animState.lastSpawn > 1.2 then animState.lastSpawn = os.clock() if math.random() < 0.7 then table.insert(animState.bullets, {x = 0, y = math.random(1, 3)}) end end -- Drohnen bewegen for i = #animState.bullets, 1, -1 do local b = animState.bullets[i] b.x = b.x + 1 if b.x < panelW then local cx = panelX + b.x local cy = h - bottomRows + b.y if cx <= w and cy <= h then setCursorPos(cx, cy) setTextColor(C.cyan) setBackgroundColor(C.bg) write("▲") end else table.remove(animState.bullets, i) end end end -- Hotel-Fassade local function drawHotel(panelX, panelW) local facade = { " [ ARASAKA GRAND HOTEL ] ", "┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐", "│█││ ││█││ ││█││ ││█││ │", "└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘" } local offset = math.floor(os.clock() * 2) % 2 for dy, line in ipairs(facade) do local ry = h - bottomRows + dy if ry <= h then for dx = 1, #line do local cx = panelX + math.floor((panelW - #line) / 2) + dx - 1 if cx >= 1 and cx <= w then local ch = line:sub(dx, dx) setCursorPos(cx, ry) if ch == "█" then setTextColor((dx + offset) % 2 == 0 and C.white or C.dim) setBackgroundColor(C.bg) write("█") else setTextColor(C.neon) setBackgroundColor(C.bg) write(ch) end end end end end end -- ========== MAIN LOOP ========== math.randomseed(os.time()) local pageIdx = 1 local logoOffset = 0 local paused = false local lastLogoMove = os.time() -- Layout local leftW = clamp(math.floor(w * 0.22), 8, 16) local panelX = leftW + 2 local panelW = w - panelX - 1 -- Init clearScreen() drawLogo(logoOffset) drawPage(PAGES[pageIdx], panelX, panelW) -- Animations-Init local currentAnim = PAGES[pageIdx].id while true do -- Timer starten local pageTimer = os.startTimer(DISPLAY_DURATION) local tickTimer = os.startTimer(TICK_INTERVAL) -- Animationszustand zurücksetzen animState = { bullets = {}, lastSpawn = 0 } local trainX = -50 while true do local event = {os.pullEventRaw()} local et = event[1] if et == "timer" then if event[2] == tickTimer then -- Logo sanft bewegen if os.time() - lastLogoMove > 2 then lastLogoMove = os.time() logoOffset = logoOffset + (math.random() < 0.5 and 1 or -1) logoOffset = clamp(logoOffset, -2, 2) drawLogo(logoOffset) end -- Animation unten fillRect(panelX, h - bottomRows + 1, panelW, bottomRows, C.bg) if currentAnim == "express" then trainX = trainX + 1 if trainX > panelW + 20 then trainX = -50 end drawICE3(panelX, panelW, trainX) elseif currentAnim == "security" then drawSecurity(panelX, panelW) elseif currentAnim == "hotel" then drawHotel(panelX, panelW) else -- Standard: Pulsierende Linie local phase = math.floor(os.clock() * 4) % 2 for i = 1, panelW, 3 do local cx = panelX + i if cx <= w then setCursorPos(cx, h - bottomRows + 2) setTextColor(phase == 0 and C.neon or C.dim) setBackgroundColor(C.bg) write("•") end end end tickTimer = os.startTimer(TICK_INTERVAL) elseif event[2] == pageTimer then -- Nächste Seite pageIdx = pageIdx % #PAGES + 1 currentAnim = PAGES[pageIdx].id drawLogo(logoOffset) drawPage(PAGES[pageIdx], panelX, panelW) break end elseif et == "monitor_touch" then local x = event[3] if x <= leftW then paused = not paused else pageIdx = pageIdx % #PAGES + 1 currentAnim = PAGES[pageIdx].id drawLogo(logoOffset) drawPage(PAGES[pageIdx], panelX, panelW) if pageTimer then os.cancelTimer(pageTimer) end pageTimer = os.startTimer(DISPLAY_DURATION) end elseif et == "key" then local key = event[2] if key == 203 or key == 205 then -- Pfeiltasten pageIdx = pageIdx % #PAGES + 1 currentAnim = PAGES[pageIdx].id drawLogo(logoOffset) drawPage(PAGES[pageIdx], panelX, panelW) if pageTimer then os.cancelTimer(pageTimer) end pageTimer = os.startTimer(DISPLAY_DURATION) end elseif et == "terminate" then clearScreen() return end end end