#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Story-Layer: Construct, weisser Hase, Mars Base, Matrix Deep (Orakel, schwarze Katze), Hell Server, Archi-Lord, Layer 0.""" import os import random from doom_matrix.engine.ui import ( Colors, slow_print, dramatic_pause, clear_screen, menu, section_title, glitch_text ) from doom_matrix.entities.enemy import Enemy from doom_matrix.systems import hacking from doom_matrix.systems.combat import run_combat from doom_matrix.world.rooms import Room, Hub from doom_matrix.world.generator import generate_filler_rooms, chain_rooms, load_item_registry # ───────────────────────────────────────────────────────────────────────── # CONSTRUCT / INTRO # ───────────────────────────────────────────────────────────────────────── def construct_intro(player, rng=None): clear_screen() slow_print(f"{Colors.GREEN}Du wachst auf...{Colors.END}", 0.05) dramatic_pause(1) slow_print(f"\n{Colors.WHITE}Um dich herum: Grüner Code. Endlose Zeilen davon.{Colors.END}") slow_print(f"{Colors.WHITE}Du kennst diesen Ort. Das Construct.{Colors.END}") dramatic_pause(0.5) slow_print(f"\n{Colors.CYAN}Morpheus Hayden:{Colors.END} {Colors.YELLOW}'Er ist wach.'{Colors.END}") dramatic_pause(0.5) slow_print(f"\n{Colors.WHITE}Eine Gestalt nähert sich. Halb Mensch, halb Metall.{Colors.END}") slow_print(f"{Colors.CYAN}Morpheus Hayden:{Colors.END} {Colors.YELLOW}'Willkommen zurück, Doom Slayer.'{Colors.END}") dramatic_pause(0.5) slow_print(f"\n{Colors.CYAN}Morpheus Hayden:{Colors.END} {Colors.YELLOW}'Die Maschinen haben etwas Neues gebaut.'{Colors.END}") slow_print(f"{Colors.CYAN}Morpheus Hayden:{Colors.END} {Colors.YELLOW}'Sie nennen es... HELL SERVER.'{Colors.END}") dramatic_pause(1) slow_print(f"\n{Colors.RED}Plötzlich ertönt ein Alarm!{Colors.END}") slow_print(f"{Colors.WHITE}Der Boden bebt. Grüner Code wird rot.{Colors.END}") dramatic_pause(0.5) slow_print(f"\n{Colors.CYAN}Trinity VEGA:{Colors.END} {Colors.YELLOW}'Wir haben Company! Agent-Signaturen überall!'{Colors.END}") dramatic_pause(0.5) slow_print(f"\n{Colors.CYAN}Morpheus Hayden:{Colors.END} {Colors.YELLOW}'Waffen. Jetzt.'{Colors.END}") slow_print(f"{Colors.WHITE}Vor dir materialisieren sich zwei Waffen:{Colors.END}") choice = menu([ ("1", "Super Shotgun (klassisch, brutal)"), ("2", "Plasma Rifle (Matrix-Style, hacking-fähig)"), ], "Wähle deine Waffe") if choice == "1": player.add_weapon("super_shotgun") player.ammo["shells"] = max(player.ammo["shells"], 20) slow_print(f"\n{Colors.YELLOW}Du greifst die Super Shotgun. Das Gewicht fühlt sich... richtig an.{Colors.END}") else: player.add_weapon("plasma_rifle") player.ammo["cells"] = max(player.ammo["cells"], 100) slow_print(f"\n{Colors.YELLOW}Du greifst das Plasma Rifle. Die Energieanzeige pulsiert im Takt des Matrix-Codes.{Colors.END}") return "white_rabbit_moment" # ───────────────────────────────────────────────────────────────────────── # DER WEISSE HASE — "Follow the white rabbit" # ───────────────────────────────────────────────────────────────────────── def white_rabbit_moment(player, rng=None): dramatic_pause(0.5) slow_print(f"\n{Colors.WHITE}Bevor der Alarm eskaliert, bemerkst du etwas an der Wand.{Colors.END}") slow_print(f"{Colors.WHITE}Ein Flackern. Ein Umriss. Klein, weiss, mit langen Ohren.{Colors.END}") slow_print(f"{Colors.WHITE}Ein Hologramm — ein weisser Hase — huscht durch eine Tür, die vorher nicht da war.{Colors.END}") dramatic_pause(1) player.flags["saw_rabbit"] = True choice = menu([ ("1", "Dem weissen Hasen folgen"), ("2", "Ignorieren — der Agent ist wichtiger"), ], "Was tust du") if choice == "1": player.flags["followed_rabbit"] = True clear_screen() section_title("FOLLOW THE WHITE RABBIT", Colors.WHITE) slow_print(f"{Colors.WHITE}Du trittst durch die Tür. Der Code um dich wird duenn, fast durchsichtig.{Colors.END}") slow_print(f"{Colors.WHITE}Fuer einen Sekundenbruchteil siehst du... etwas anderes.{Colors.END}") dramatic_pause(1) try: real_user = os.getlogin() except Exception: real_user = "UNBEKANNT" glitch_text_line = f"BENUTZER: {real_user} // SITZUNG AKTIV // TERMINAL ERKANNT" slow_print(f"{Colors.DIM}{glitch_text(glitch_text_line, 0.25)}{Colors.END}", 0.01) dramatic_pause(0.5) slow_print(f"{Colors.WHITE}Ein Kaninchenbau aus Zahlen faellt endlos nach unten.{Colors.END}") slow_print(f"{Colors.WHITE}Du siehst dich selbst -- nicht als Slayer, nicht als Neo.{Colors.END}") slow_print(f"{Colors.WHITE}Als Beobachter. Als jemand, der das hier von AUSSEN spielt.{Colors.END}") dramatic_pause(1) slow_print(f"\n{Colors.CYAN}Morpheus Hayden (von weit weg):{Colors.END} {Colors.YELLOW}'Wo bist du?! Der Agent ist da!'{Colors.END}") slow_print(f"{Colors.WHITE}Die Tür schliesst sich. Der Kaninchenbau verschwindet -- fuer jetzt.{Colors.END}") registry = load_item_registry() token = registry.get("praetor_token") if token: player.inventory.add(token) player.praetor_tokens += 1 slow_print(f"{Colors.GREEN}Du haltst einen Praetor-Token in der Hand, den es vorher nicht gab.{Colors.END}") else: slow_print(f"\n{Colors.WHITE}Du ignorierst das Flackern. Spaeter, vielleicht.{Colors.END}") slow_print(f"{Colors.DIM}(Manche Kaninchenbaue oeffnen sich nur einmal.){Colors.END}") dramatic_pause(0.5) slow_print(f"\n{Colors.RED}KRACH!{Colors.END}") slow_print(f"{Colors.WHITE}Die Wand explodiert. Ein Agent stürmt herein — aber er sieht... falsch aus.{Colors.END}") slow_print(f"{Colors.WHITE}Sein Anzug ist zerrissen. Unter der Haut: Schuppen. Hörner.{Colors.END}") return "agent_fight" # ───────────────────────────────────────────────────────────────────────── # ERSTER KAMPF # ───────────────────────────────────────────────────────────────────────── def agent_fight(player, rng=None): rng = rng or random enemy = Enemy.create("agent_imp") victory = run_combat(player, [enemy], title="KAMPF: AGENT IMP", rng=rng) if not victory: return "game_over" slow_print(f"{Colors.YELLOW}Sein Körper zerfällt zu grünem Code und verschwindet.{Colors.END}") dramatic_pause(1) return "after_fight" def after_fight(player, rng=None): slow_print(f"\n{Colors.CYAN}Morpheus Hayden:{Colors.END} {Colors.YELLOW}'Beeindruckend. Aber das war nur ein Scout.'{Colors.END}") slow_print(f"{Colors.CYAN}Trinity VEGA:{Colors.END} {Colors.YELLOW}'Wir müssen hier raus. Der HELL SERVER wartet.'{Colors.END}") dramatic_pause(0.5) slow_print(f"\n{Colors.WHITE}Vor dir öffnen sich drei Portale:{Colors.END}") choice = menu([ ("1", f"{Colors.RED}Roter Tunnel{Colors.END} — zurück zur Mars-UAC-Base"), ("2", f"{Colors.GREEN}Grüner Code-Strom{Colors.END} — tiefer in die Matrix"), ("3", f"{Colors.MAGENTA}Schwarzes Loch{Colors.END} — direkt zum HELL SERVER"), ], "Wähle deinen Weg") if choice == "1": player.layer = 4 return "mars_base" elif choice == "2": player.layer = 3 return "matrix_deep" else: player.layer = 2 return "hell_server" # ───────────────────────────────────────────────────────────────────────── # MARS UAC BASE (Hub) # ───────────────────────────────────────────────────────────────────────── def mars_base(player, rng=None): rng = rng or random clear_screen() slow_print(f"\n{Colors.RED}{Colors.BOLD}═══ MARS UAC BASE ═══{Colors.END}") slow_print(f"{Colors.WHITE}Du materialisierst dich in einer kalten, roten Landschaft.{Colors.END}") slow_print(f"{Colors.WHITE}Die UAC-Base liegt in Trümmern. Dämonen-Überreste überall.{Colors.END}") dramatic_pause(1) registry = load_item_registry() def armory_event(p, ctx): slow_print(f"\n{Colors.GREEN}Du findest den BFG 10000!{Colors.END}") p.add_weapon("bfg10000") p.ammo["bfg"] = max(p.ammo["bfg"], 3) slow_print(f"{Colors.YELLOW}'Big Fucking Gun' — die ultimative Waffe.{Colors.END}") slow_print(f"{Colors.RED}WARNUNG: Jeder Schuss verbraucht enorme Energie.{Colors.END}") return None def control_event(p, ctx): slow_print(f"\n{Colors.GREEN}Ein Terminal flackert. Eine Nachricht von Dr. Betruger...{Colors.END}") slow_print(f"{Colors.DIM}'Sie haben uns angelogen. Die Maschinen und die Dämonen...'{Colors.END}") slow_print(f"{Colors.DIM}'...sie arbeiten zusammen. Die Matrix IST die Hölle.'{Colors.END}") dramatic_pause(0.5) slow_print(f"{Colors.GREEN}Du versuchst, das Kontrollzentrum zu hacken...{Colors.END}") success = hacking.attempt_hack(p, firewall=10, rng=rng) if success: slow_print(f"{Colors.GREEN}Zugriff gewaehrt! Ein verstecktes Fach oeffnet sich.{Colors.END}") frag = registry.get("crucible_fragment") p.inventory.add(frag) slow_print(f"{Colors.YELLOW}Du findest ein Crucible-Fragment! ({p.inventory.crucible_fragments}/3){Colors.END}") else: slow_print(f"{Colors.RED}Zugriff verweigert. Ein stiller Alarm wird ausgeloest.{Colors.END}") return None def vault_event(p, ctx): if p.inventory.has_keycard("red"): slow_print(f"\n{Colors.GREEN}Deine rote Keycard oeffnet den Waffentresor.{Colors.END}") p.inventory.add(registry["ammo_pack"]) p.inventory.add(registry["armor_shard"]) slow_print(f"{Colors.GREEN}Ammo-Pack und Armor-Shard eingesammelt.{Colors.END}") else: slow_print(f"\n{Colors.RED}Der Waffentresor ist verriegelt. Du brauchst eine rote Keycard.{Colors.END}") return None armory = Room("mars_armory", "Waffenkammer", "Zerbrochene Regale, geschmolzenes Metall. Etwas Grosses liegt unter den Truemmern.", item_ids=["keycard_red"], on_enter=armory_event) control = Room("mars_control", "Kontrollzentrum", "Bildschirme voller Fehlermeldungen. Ein Terminal ist noch aktiv.", on_enter=control_event) vault = Room("mars_vault", "Waffentresor", "Eine schwere, versiegelte Tuer. Rot markiert.", locked_by="red", on_enter=vault_event) filler = generate_filler_rooms("mars", 2, rng) hub_start = Room("mars_hub", "Zentraler Korridor", "Der Knotenpunkt der Basis. Drei Wege fuehren tiefer hinein.") hub_start.exits = { "Zur Waffenkammer": armory.room_id, "Zum Kontrollzentrum": control.room_id, "Zum Waffentresor": vault.room_id, "Weiter erkunden": filler[0].room_id, } armory.exits = {"Zurueck zum Korridor": hub_start.room_id} control.exits = {"Zurueck zum Korridor": hub_start.room_id} vault.exits = {"Zurueck zum Korridor": hub_start.room_id} chain_rooms(filler, "Weiter") filler[-1].exits["Zum Portal (weiter zum HELL SERVER)"] = "mars_exit" def portal_event(p, ctx): slow_print(f"\n{Colors.YELLOW}Du aktivierst das Portal...{Colors.END}") return ("leave", "portal_used") exit_room = Room("mars_exit", "Portalraum", "Ein pulsierendes, schwarzes Portal schwebt in der Mitte des Raums.", on_enter=portal_event) all_rooms = [hub_start, armory, control, vault, exit_room] + filler hub = Hub(all_rooms, hub_start.room_id) hub.explore(player, registry) player.flags["visited_mars"] = True if not player.flags.get("visited_matrix"): slow_print(f"{Colors.YELLOW}Das Portal führt nicht zur Hölle -- es führt tiefer in die Matrix.{Colors.END}") return "matrix_deep" slow_print(f"{Colors.YELLOW}Das Portal führt zum HELL SERVER.{Colors.END}") player.layer = 2 return "hell_server" # ───────────────────────────────────────────────────────────────────────── # MATRIX DEEP — Orakel, schwarze Katze (Deja-vu-Glitch), Agent Smith # ───────────────────────────────────────────────────────────────────────── def _black_cat_glitch(player, rng): """Kein Item, kein weisses Fell -- eine SCHWARZE Katze, die zweimal EXAKT denselben Weg laeuft. Das ist kein Zufall: es ist ein Zeichen dafuer, dass jemand gerade den Code der Matrix veraendert hat ('ein Fehler in der Matrix').""" section_title("DEJA VU", Colors.MAGENTA) cat_line = "Eine schwarze Katze schleicht am Tuerrahmen vorbei, setzt zum Sprung an, verschwindet." slow_print(f"{Colors.WHITE}{cat_line}{Colors.END}") dramatic_pause(1) slow_print(f"\n{Colors.DIM}...{Colors.END}") dramatic_pause(0.5) # Exakt derselbe Satz, bewusst identisch -- das IST der Bug. slow_print(f"{Colors.WHITE}{cat_line}{Colors.END}") dramatic_pause(0.3) slow_print(f"\n{Colors.MAGENTA}Trinity VEGA erstarrt.{Colors.END}") slow_print(f"{Colors.CYAN}Trinity VEGA:{Colors.END} {Colors.YELLOW}'Das war... derselbe Moment. Exakt derselbe.'{Colors.END}") slow_print(f"{Colors.CYAN}Trinity VEGA:{Colors.END} {Colors.YELLOW}'Ein Deja-vu ist kein Zufall. Es bedeutet, dass sich gerade{Colors.END}") slow_print(f"{Colors.CYAN}Trinity VEGA:{Colors.END} {Colors.YELLOW}etwas im Code veraendert hat. Jemand manipuliert diesen Server. Jetzt.'{Colors.END}") dramatic_pause(1) player.flags["cat_glitch_count"] += 1 player.flags["cat_glitch_seen"] = True choice = menu([ ("1", "Dem Glitch nachspueren (Hacking-Check)"), ("2", "Ignorieren und weitergehen"), ], "Reaktion") if choice == "1": success = hacking.attempt_hack(player, firewall=12, rng=rng) if success: slow_print(f"\n{Colors.GREEN}Du findest die Bruchstelle im Code -- eine Naht, wo etwas neu geschrieben wurde.{Colors.END}") slow_print(f"{Colors.GREEN}Ein Log-Fragment sickert durch: {Colors.DIM}'...Hayden-Prozess re-kompiliert um 03:14...'{Colors.END}") registry = load_item_registry() player.inventory.add(registry["logfile"]) player.gain_corruption(2) else: slow_print(f"\n{Colors.RED}Die Naht schliesst sich, bevor du sie greifen kannst.{Colors.END}") else: slow_print(f"\n{Colors.WHITE}Du gehst weiter. Manche Bugs loest man besser nicht.{Colors.END}") def _oracle_scene(player, rng): clear_screen() section_title("DIE KUeCHE DES ORAKELS", Colors.YELLOW) slow_print(f"{Colors.WHITE}Der Geruch von frisch gebackenen Keksen fuehlt sich falsch an in einem Ort aus Code.{Colors.END}") slow_print(f"{Colors.WHITE}Eine aeltere Frau steht am Herd, ohne sich umzudrehen.{Colors.END}") dramatic_pause(0.5) slow_print(f"\n{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Setz dich, Slayer. Oder Neo. Ich hab schon beide Kekse gebacken.'{Colors.END}") dramatic_pause(0.5) if player.flags.get("followed_rabbit"): slow_print(f"\n{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Du bist dem Hasen gefolgt. Gut. Nicht viele tun das zweimal.'{Colors.END}") else: slow_print(f"\n{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Du hast den Hasen ignoriert. Verstaendlich. Kaninchenbaue sind unbequem.'{Colors.END}") if player.corruption >= 30: slow_print(f"\n{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Du riechst nach Schwefel, Kind. Das waechst schneller, als dir lieb ist.'{Colors.END}") dramatic_pause(0.5) slow_print(f"\n{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Ich sag dir nicht, was passieren wird. Ich sag dir nur:{Colors.END}") slow_print(f"{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}Morpheus glaubt an dich mehr, als er an sich selbst glaubt.{Colors.END}") slow_print(f"{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}Frag dich mal, warum.'{Colors.END}") dramatic_pause(1) choice = menu([ ("1", "'Bin ich Der Eine?'"), ("2", "'Ist Morpheus, wer er zu sein scheint?'"), ("3", "'Was ist der HELL SERVER wirklich?'"), ], "Deine Frage") if choice == "1": slow_print(f"\n{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Falsche Frage. Es geht nicht darum, was du bist.'{Colors.END}") slow_print(f"{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Es geht darum, was du als Naechstes tust.'{Colors.END}") elif choice == "2": slow_print(f"\n{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'...'{Colors.END}") slow_print(f"{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Manche Antworten wuerden dir mehr schaden als der Cyberdemon.'{Colors.END}") slow_print(f"{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Behalt einfach im Hinterkopf: nicht jeder, der dich rettet, luegt nicht dabei.'{Colors.END}") else: slow_print(f"\n{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Ein Generator. Er wandelt Seelen in Strom und Strom in Daemonen um.'{Colors.END}") slow_print(f"{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Die Matrix laeuft nicht NEBEN der Hoelle. Sie laeuft AUF ihr.'{Colors.END}") dramatic_pause(1) slow_print(f"\n{Colors.YELLOW}Das Orakel:{Colors.END} {Colors.WHITE}'Hier. Nimm das. Du wirst es brauchen -- oder auch nicht.'{Colors.END}") registry = load_item_registry() player.inventory.add(registry["crucible_fragment"]) slow_print(f"{Colors.YELLOW}Du erhaeltst ein Crucible-Fragment! ({player.inventory.crucible_fragments}/3){Colors.END}") player.flags["met_oracle"] = True def matrix_deep(player, rng=None): rng = rng or random clear_screen() slow_print(f"\n{Colors.GREEN}{Colors.BOLD}═══ TIEF IN DER MATRIX ═══{Colors.END}") slow_print(f"{Colors.WHITE}Der Code wird dichter. Realität ist hier nur eine Option.{Colors.END}") slow_print(f"{Colors.WHITE}Du siehst endlose Reihen von Menschen in Stasiskapseln —{Colors.END}") slow_print(f"{Colors.WHITE}aber sie spielen nicht nur Sims. Sie RENDERN.{Colors.END}") dramatic_pause(1) _black_cat_glitch(player, rng) dramatic_pause(0.5) _oracle_scene(player, rng) dramatic_pause(1) clear_screen() slow_print(f"\n{Colors.CYAN}Ein Agent erscheint — aber er sieht normal aus. Smith?{Colors.END}") slow_print(f"{Colors.CYAN}Agent Smith:{Colors.END} {Colors.YELLOW}'Mr. Anderson... oder sollte ich sagen...{Colors.END}") slow_print(f"{Colors.CYAN}Agent Smith:{Colors.END} {Colors.YELLOW}'...Doom Slayer?'{Colors.END}") dramatic_pause(1) slow_print(f"\n{Colors.RED}Smith lächelt. Sein Lächeln ist zu breit. Zu viele Zähne.{Colors.END}") choice = menu([ ("1", "'Mein Name ist Neo.' (Klassisch)"), ("2", "'Rip and tear, until it is done.' (Doom)"), ("3", "Beides gleichzeitig sagen (Chaos)"), ], "Deine Antwort") smith_clones = 1 if choice == "1": slow_print(f"\n{Colors.GREEN}'Mein Name ist Neo.'{Colors.END}") slow_print(f"{Colors.CYAN}Smith:{Colors.END} {Colors.YELLOW}'Wie vorhersehbar.'{Colors.END}") slow_print(f"{Colors.RED}Smith multipliziert sich! Klone umzingeln dich!{Colors.END}") smith_clones = 3 elif choice == "2": slow_print(f"\n{Colors.RED}'Rip and tear, until it is done.'{Colors.END}") slow_print(f"{Colors.CYAN}Smith:{Colors.END} {Colors.YELLOW}'Interessant. Sie haben sich verändert.'{Colors.END}") slow_print(f"{Colors.YELLOW}Smith zögert. Er kennt diese Worte nicht.{Colors.END}") player.add_armor(20) smith_clones = 1 else: slow_print(f"\n{Colors.GREEN}'Mein Name ist Neo...'{Colors.END}") dramatic_pause(0.5) slow_print(f"{Colors.RED}'...und ICH WERDE ALLES ZERREISSEN!'{Colors.END}") slow_print(f"{Colors.YELLOW}Du aktivierst Bullet Time UND Berserker-Mode gleichzeitig!{Colors.END}") player.heal(20) player.add_armor(30) player.gain_corruption(3) smith_clones = 2 enemies = [Enemy.create("agent_clone") for _ in range(smith_clones)] enemies[0].name = "Agent Smith" victory = run_combat(player, enemies, title="KAMPF: AGENT SMITH", rng=rng) if not victory: return "game_over" slow_print(f"\n{Colors.RED}Der Kampf ist vorbei. Aber Smith ist nicht allein...{Colors.END}") slow_print(f"{Colors.MAGENTA}Hinter ihm öffnet sich ein Portal.{Colors.END}") player.flags["visited_matrix"] = True if not player.flags.get("visited_mars"): slow_print(f"{Colors.MAGENTA}Es führt nicht zur Hölle -- es führt zur Mars-Basis.{Colors.END}") return "mars_base" slow_print(f"{Colors.MAGENTA}Es führt zur Hölle.{Colors.END}") player.layer = 2 return "hell_server" # ───────────────────────────────────────────────────────────────────────── # HELL SERVER (Hub + Boss) # ───────────────────────────────────────────────────────────────────────── def hell_server(player, rng=None): rng = rng or random clear_screen() slow_print(f"\n{Colors.MAGENTA}{Colors.BOLD}═══ HELL SERVER ═══{Colors.END}") slow_print(f"{Colors.WHITE}Du betrittst einen Raum, der nicht existieren sollte.{Colors.END}") slow_print(f"{Colors.WHITE}Lava-Flüsse aus geschmolzenem Silizium.{Colors.END}") slow_print(f"{Colors.WHITE}Dämonen mit Netzwerk-Kabeln statt Nervensträngen.{Colors.END}") dramatic_pause(1) registry = load_item_registry() filler = generate_filler_rooms("hell", 2, rng, seed_offset=10) chain_rooms(filler, "Tiefer") def altar_event(p, ctx): slow_print(f"\n{Colors.GREEN}Auf einem Altar aus Motherboards liegt ein Splitter reinen Codes.{Colors.END}") registry_local = load_item_registry() p.inventory.add(registry_local["crucible_fragment"]) slow_print(f"{Colors.YELLOW}Crucible-Fragment gefunden! ({p.inventory.crucible_fragments}/3){Colors.END}") return None altar = Room("hell_altar", "Altarraum", "Ein Altar aus verschmolzenen Platinen. Etwas glueht darauf.", on_enter=altar_event) boss_state = {"fought": False} def boss_event(p, ctx): slow_print(f"\n{Colors.RED}Ein Cyberdemon tritt aus den Schatten.{Colors.END}") slow_print(f"{Colors.RED}Sein Körper ist halb Fleisch, halb Server-Rack.{Colors.END}") slow_print(f"{Colors.RED}Seine Raketenwerfer sind mit Ethernet-Kabeln verbunden.{Colors.END}") dramatic_pause(1) slow_print(f"\n{Colors.CYAN}Trinity VEGA:{Colors.END} {Colors.YELLOW}'Das ist es. Der HELL SERVER.'{Colors.END}") slow_print(f"{Colors.CYAN}Trinity VEGA:{Colors.END} {Colors.YELLOW}'Wenn wir den zerstören, fällt die gesamte Simulation!'{Colors.END}") boss = Enemy.create("cyberdemon") victory = run_combat(player, [boss], title="BOSS: CYBERDEMON", rng=rng) if not victory: return ("leave", "game_over") slow_print(f"\n{Colors.YELLOW}Der Cyberdemon zerfaellt in Bytes und Asche!{Colors.END}") slow_print(f"{Colors.GREEN}Der HELL SERVER stürzt ein!{Colors.END}") boss_state["fought"] = True return ("leave", "final_boss") boss_room = Room("hell_boss", "Serverkern", "Die Hitze hier ist unertraeglich. Etwas Grosses wartet.", on_enter=boss_event, one_time_event=False) hub_start = Room("hell_hub", "Lavaspalte", "Gluehende Risse durchziehen den Boden. Zwei Wege fuehren tiefer.") hub_start.exits = { "Zum Altarraum": altar.room_id, "Weiter erkunden": filler[0].room_id, "Zum Serverkern (Boss)": boss_room.room_id, } altar.exits = {"Zurueck": hub_start.room_id} filler[-1].exits["Zum Serverkern (Boss)"] = boss_room.room_id all_rooms = [hub_start, altar, boss_room] + filler hub = Hub(all_rooms, hub_start.room_id) result = hub.explore(player, registry) if isinstance(result, tuple) and result[0] == "leave": return result[1] return "final_boss" # ───────────────────────────────────────────────────────────────────────── # FINAL BOSS: DER ARCHI-LORD # ───────────────────────────────────────────────────────────────────────── def final_boss(player, rng=None): rng = rng or random dramatic_pause(1) clear_screen() slow_print(f"\n{Colors.YELLOW}{Colors.BOLD}═══ DER ARCHI-LORD ═══{Colors.END}") slow_print(f"{Colors.WHITE}Hinter den Trümmern des HELL SERVERS öffnet sich eine weiße Tür.{Colors.END}") slow_print(f"{Colors.WHITE}Dahinter: Ein Raum aus reinem Licht. Und Code.{Colors.END}") dramatic_pause(1) slow_print(f"\n{Colors.YELLOW}Eine Gestalt materialisiert — halb Der Architekt, halb Dark Lord Davoth.{Colors.END}") slow_print(f"{Colors.YELLOW}Der Archi-Lord.{Colors.END}") dramatic_pause(1) slow_print(f"\n{Colors.YELLOW}Archi-Lord:{Colors.END} {Colors.WHITE}'Willkommen, Doom Slayer. Oder Neo. Oder wer auch immer Sie heute sind.'{Colors.END}") slow_print(f"{Colors.YELLOW}Archi-Lord:{Colors.END} {Colors.WHITE}'Sie haben beide Systeme zerstört. Die Matrix. Die Hölle.'{Colors.END}") slow_print(f"{Colors.YELLOW}Archi-Lord:{Colors.END} {Colors.WHITE}'Was erwarten Sie als Nächstes? Eine Medaille?'{Colors.END}") if player.inventory.crucible_fragments >= 3: dramatic_pause(0.5) slow_print(f"\n{Colors.YELLOW}Archi-Lord:{Colors.END} {Colors.WHITE}'...Sie haben alle drei Fragmente. Wie unerwartet.'{Colors.END}") dramatic_pause(1) choice = menu([ ("1", "'Ich will die Wahrheit.'"), ("2", "'Ich will alles zerstören.'"), ("3", "'Ich will die Kontrolle uebernehmen.'"), ("4", "'Ich will... einen neuen Spielstand.'"), ], "Deine Antwort") player.flags["final_choice"] = choice if choice == "1": slow_print(f"\n{Colors.YELLOW}Archi-Lord:{Colors.END} {Colors.WHITE}'Die Wahrheit? Die Wahrheit ist...'{Colors.END}") dramatic_pause(1.5) slow_print(f"{Colors.YELLOW}Archi-Lord:{Colors.END} {Colors.WHITE}'...dass Sie nur Code sind. In meinem Code. In meinem Spiel.'{Colors.END}") elif choice == "2": slow_print(f"\n{Colors.RED}Du aktivierst alle Waffen gleichzeitig.{Colors.END}") slow_print(f"{Colors.RED}Super Shotgun. Plasma Rifle. BFG 10000. Fäuste.{Colors.END}") player.gain_corruption(15) elif choice == "3": slow_print(f"\n{Colors.MAGENTA}'Ich brauche keine Wahrheit. Ich brauche die Zuegel.'{Colors.END}") player.gain_corruption(25) else: slow_print(f"\n{Colors.GREEN}Du lächelst.{Colors.END}") slow_print(f"{Colors.GREEN}'Ich will einen neuen Spielstand. Mit Cheats.'{Colors.END}") slow_print(f"{Colors.YELLOW}Archi-Lord:{Colors.END} {Colors.WHITE}'...Interessant.'{Colors.END}") if player.inventory.crucible_fragments >= 3 and not player.has_weapon("crucible"): dramatic_pause(0.5) use_crucible = menu([ ("1", "Die drei Fragmente zum Crucible Sword verschmelzen"), ("2", "Fragmente aufbewahren"), ], "Du spuerst die Fragmente pulsieren") if use_crucible == "1": player.add_weapon("crucible") slow_print(f"\n{Colors.YELLOW}Die Fragmente verschmelzen zum Crucible Sword!{Colors.END}") dramatic_pause(1) boss = Enemy.create("archi_lord") victory = run_combat(player, [boss], title="ENDBOSS: DER ARCHI-LORD", rng=rng) if not victory: return "game_over" return "layer_zero_check" # ───────────────────────────────────────────────────────────────────────── # LAYER 0 — das geheime, wahre Ende ("Wake Up") # ───────────────────────────────────────────────────────────────────────── def layer_zero_unlocked(player): return player.inventory.crucible_fragments >= 3 and player.flags.get("followed_rabbit") def layer_zero_check(player, rng=None): if not layer_zero_unlocked(player): return "ending" dramatic_pause(1) clear_screen() section_title("LAYER 0", Colors.WHITE) slow_print(f"{Colors.WHITE}Der Archi-Lord zerfaellt -- aber diesmal reorganisiert sich der Code nicht.{Colors.END}") slow_print(f"{Colors.WHITE}Die drei Crucible-Fragmente in deiner Hand ziehen sich gegenseitig an.{Colors.END}") slow_print(f"{Colors.WHITE}Du erinnerst dich an den Hasen. An den Kaninchenbau, den du einmal betreten hast.{Colors.END}") dramatic_pause(1) slow_print(f"\n{Colors.WHITE}Der Raum um dich loest sich nicht in Trümmer auf. Er loest sich in {Colors.DIM}Syntax{Colors.END}{Colors.WHITE} auf.{Colors.END}") try: real_user = os.getlogin() except Exception: real_user = "SPIELER" slow_print(f"{Colors.DIM}{glitch_text(f'PROZESS {real_user} HAT DIE SIMULATION ERKANNT', 0.2)}{Colors.END}", 0.01) dramatic_pause(1) slow_print(f"\n{Colors.WHITE}Kein Morpheus. Kein Orakel. Kein Archi-Lord.{Colors.END}") slow_print(f"{Colors.WHITE}Nur ein Terminal-Fenster. Und du, davor.{Colors.END}") slow_print(f"{Colors.WHITE}Layer 4. Layer 3. Layer 2. Layer 1. Und jetzt: {Colors.BOLD}Layer 0{Colors.END}{Colors.WHITE}.{Colors.END}") dramatic_pause(1) slow_print(f"\n{Colors.GREEN}Es gibt keinen loeffel. Es gab nie ein Spiel, das dich gespielt hat.{Colors.END}") slow_print(f"{Colors.GREEN}Es gab nur dich, das Terminal, und die Entscheidung weiterzulesen.{Colors.END}") player.layer = 0 player.flags["reached_layer_zero"] = True dramatic_pause(1.5) return "ending"