;;; alien-rpg.el --- Přístupný herní engine pro Alien RPG -*- lexical-binding: t; -*-
;;
;; Přístupný systém pro nevidomého hráče Alien RPG.
;; Ovládání přes SPC G (Doom Emacs).
;; Žádné soubory, žádné scrollování. Jeden stisk = informace.
;;
;;; Code:

(require 'cl-lib)

;; ====================================================================
;; STANICE
;; ====================================================================

(defvar alien-rpg-station-name "USCSS CETORHINA"
  "Jméno stanice.")

;; ====================================================================
;; PALUBY
;; ====================================================================

(defvar alien-rpg-decks
  '((:id "A" :name "Astrometrická observatoř"
     :purpose "Astronomické pozorování"
     :size "Mala (A2)" :scale "5 m" :position 1
     :notes "Izolovaná. Přístup pouze z paluby B (západ).")

    (:id "B" :name "Řízení provozu"
     :purpose "Velitelský můstek"
     :size "Středni (A2)" :scale "5 m" :position 2
     :notes "MU/TH/UR (hlavni pocitac), řídící středisko.")

    (:id "C" :name "Zdraví a odpočinek"
     :purpose "Medicína, rekreace, botanika"
     :size "Středni (A2)" :scale "5 m" :position 3
     :notes "Ošetřovna, laboratoř, arboretum.")

    (:id "D" :name "Recepce a výzkum"
     :purpose "Vědecké laboratoře, příjem návštěvníků"
     :size "Středni (A2)" :scale "5 m" :position 4
     :notes "Návštěvnický dokovací port (přístup do vesmíru).")

    (:id "E" :name "Kajuty a stravování"
     :purpose "Ubytování posádky, stravování"
     :size "Středni (A2)" :scale "5 m" :position 5
     :notes "6 kajut, jídelna, tělocvična.")

    (:id "F" :name "Nápravné zařízení"
     :purpose "Vězeňské zařízení"
     :size "Velka (A1)" :scale "5 m" :position 6
     :notes "Zbrojnice. 6 průlezů na G.")

    (:id "G" :name "Hangáry a údržba"
     :purpose "Hangáry, dokovací porty, údržba"
     :size "Velka (A1)" :scale "5 m" :position 7
     :notes "2 hangáry, 2 dok. porty, 4 EVA pody, kryopody. 9 průlezů.")

    (:id "H" :name "Průmyslový komplex"
     :purpose "Energetika, průmysl, tavení"
     :size "Velmi velka (A1, 10m meritko)" :scale "10 m" :position 8
     :notes "NEJVĚTŠÍ paluba. Nádrž toxických plynů, plasma, dílny.")

    (:id "I" :name "Záchranné moduly"
     :purpose "Evakuace — únikové kapsle"
     :size "Středni (A2)" :scale "5 m" :position 9
     :notes "Záchranné moduly/kapsle.")

    (:id "J" :name "Strojovna reaktoru"
     :purpose "Energetický reaktor"
     :size "Středni (A2)" :scale "5 m" :position 10
     :notes "Nejnižší paluba. 3 baterie. Slepá ulička."))
  "Data o palubách.")

;; ====================================================================
;; MISTNOSTI
;; ====================================================================

(defvar alien-rpg-rooms
  '(;; === Paluba A ===
    (:id "A-observator" :deck "A" :name "Observatoř"
     :location "Celá paluba" :note "Jeden otevreny prostor — kopule."
     :desc "Kopulovitý prostor s panoramatickými okny do vesmíru. Teleskopy a citlivé přístroje. Izolované místo — jediný únik zpět na palubu B."
     :connections ("B-pruchod-A"))

    ;; === Paluba B ===
    (:id "B-observator" :deck "B" :name "Observatoř"
     :location "Sever" :note ""
     :desc "Pozorovací místnost na severu velitelské paluby. Konzole pro sledování okolního prostoru."
     :connections ("B-kancelar-vedouciho" "B-ridici-stredisko"))
    (:id "B-kancelar-vedouciho" :deck "B" :name "Kancelář vedoucího stanice"
     :location "Sever-střed" :note ""
     :desc "Kancelář velitele stanice. Pracovní stůl, terminál, trezor. Může obsahovat důvěrné dokumenty a přístupové kódy."
     :connections ("B-observator" "B-zasedaci" "B-chodba"))
    (:id "B-zasedaci" :deck "B" :name "Zasedací místnost"
     :location "Severozápad" :note ""
     :desc "Konferenční místnost s velkým stolem a křesly. Komunikační panel na stěně."
     :connections ("B-kancelar-vedouciho" "B-pruchod-A"))
    (:id "B-ridici-stredisko" :deck "B" :name "Řídící středisko"
     :location "Severovýchod" :note "Hlavní velín."
     :desc "Hlavní velín stanice. Řady konzolí, displeje se stavy systémů, komunikační panel. Odtud se řídí celá stanice."
     :connections ("B-observator" "B-wc-horni" "B-chodba"))
    (:id "B-wc-horni" :deck "B" :name "WC (horní)"
     :location "Východ" :note ""
     :desc "Malá toaleta. Nic zajímavého."
     :connections ("B-ridici-stredisko" "B-wc-dolni"))
    (:id "B-wc-dolni" :deck "B" :name "WC (dolní)"
     :location "Východ" :note ""
     :desc "Malá toaleta pod horním WC."
     :connections ("B-wc-horni" "B-chodba"))
    (:id "B-pruchod-A" :deck "B" :name "Průchod na palubu A"
     :location "Západ" :note "Jediný přístup na palubu A."
     :desc "Zabezpečený průchod na západní straně. Jediná cesta na izolovanou observatoř paluby A."
     :connections ("B-zasedaci" "B-chodba" "A-observator"))
    (:id "B-chodba" :deck "B" :name "Hlavní chodba"
     :location "Střed" :note ""
     :desc "Centrální koridor paluby B. Rozcestí — spojuje velín, kanceláře, šachtu a MU/TH/UR."
     :connections ("B-kancelar-vedouciho" "B-ridici-stredisko" "B-pruchod-A"
                   "B-wc-dolni" "B-mu-th-ur" "B-centralni-sachta"))
    (:id "B-mu-th-ur" :deck "B" :name "MU/TH/UR"
     :location "Jih-střed" :note "Hlavní počítač stanice (Mother)."
     :desc "Místnost hlavního počítače stanice — Mother. Terminály pro přístup k databázím, logům, senzorům a řízení systémů celé stanice."
     :connections ("B-chodba" "B-kuchynka"))
    (:id "B-kuchynka" :deck "B" :name "Kuchyňka"
     :location "Jihovýchod" :note ""
     :desc "Malá kuchyňka pro posádku velitelské paluby. Automat na nápoje, mikrovlnka."
     :connections ("B-mu-th-ur" "B-sklad"))
    (:id "B-sklad" :deck "B" :name "Sklad"
     :location "Jihovýchod" :note ""
     :desc "Malý sklad s policemi. Kancelářské potřeby, náhradní díly pro elektroniku."
     :connections ("B-kuchynka"))
    (:id "B-centralni-sachta" :deck "B" :name "Centrální šachta"
     :location "Střed" :note ""
     :desc "Vertikální šachta spojující paluby B-J. Žebříky a servisní plošiny. Paluba A zde NENÍ — přístup jen přes průchod."
     :connections ("B-chodba"
                   "C-centralni-sachta" "D-centralni-sachta" "E-centralni-sachta"
                   "F-centralni-sachta" "G-centralni-sachta" "H-centralni-sachta"
                   "I-centralni-sachta" "J-centralni-sachta"))

    ;; === Paluba C ===
    (:id "C-spolecenska" :deck "C" :name "Společenská místnost"
     :location "Sever" :note ""
     :desc "Velká odpočinková místnost. Pohovky, stoly, obrazovky. Místo setkávání posádky."
     :connections ("C-sauna" "C-wc" "C-osetrovna" "C-zotavovaci" "C-centralni-sachta"))
    (:id "C-sauna" :deck "C" :name "Sauna a sprchy"
     :location "Severovýchod" :note ""
     :desc "Sauna a sprchový kout. Vlhko, pára, omezený výhled — takticky nebezpečné."
     :connections ("C-spolecenska"))
    (:id "C-wc" :deck "C" :name "WC"
     :location "Východ" :note ""
     :desc "Toaleta paluby C."
     :connections ("C-spolecenska"))
    (:id "C-osetrovna" :deck "C" :name "Ošetřovna a laboratoř"
     :location "Severozápad" :note "Léčení, analýza vzorků."
     :desc "Ošetřovna s lékařským vybavením a analytická laboratoř. Lůžko, mikroskop, lékárnička, vzorkovnice. Klíčové místo pro léčení a výzkum."
     :connections ("C-spolecenska" "C-kajuta-lekar" "C-centralni-sachta"))
    (:id "C-zotavovaci" :deck "C" :name "Zotavovací místnost"
     :location "Severovýchod" :note ""
     :desc "Klidná místnost pro rekonvalescenci. Lůžko, monitoring životních funkcí."
     :connections ("C-spolecenska" "C-kajuta-vedouci" "C-centralni-sachta"))
    (:id "C-kajuta-lekar" :deck "C" :name "Kajuta lékařského důstojníka"
     :location "Západ" :note ""
     :desc "Soukromá kajuta a pracoviště lékaře. Osobní terminál, lékařská dokumentace."
     :connections ("C-osetrovna" "C-arboretum" "C-centralni-sachta"))
    (:id "C-kajuta-vedouci" :deck "C" :name "Kajuta vedoucího stanice"
     :location "Východ" :note ""
     :desc "Soukromé bydlení velitele stanice. Prostornější než běžné kajuty. Může obsahovat speciální přístupy nebo dokumenty."
     :connections ("C-zotavovaci" "C-arboretum" "C-centralni-sachta"))
    (:id "C-arboretum" :deck "C" :name "Arboretum"
     :location "Střed-jih" :note "Velký zelený prostor."
     :desc "Rozlehlý botanický prostor s živými stromy a rostlinami. Umělé osvětlení simuluje denní cyklus. Vegetace poskytuje úkryt, ale i skrýš pro nepřátele."
     :connections ("C-kajuta-lekar" "C-kajuta-vedouci" "C-centralni-sachta"
                   "C-hydro-z" "C-hydro-v"))
    (:id "C-hydro-z" :deck "C" :name "Hydroponická zahrada (Z)"
     :location "Jihozápad" :note ""
     :desc "Hydroponická zahrada — pěstování potravin bez půdy. Regály s rostlinami, vodní systém. Slepá ulička."
     :connections ("C-arboretum"))
    (:id "C-hydro-v" :deck "C" :name "Hydroponická zahrada (V)"
     :location "Jihovýchod" :note ""
     :desc "Hydroponická zahrada — pěstování potravin. Regály s rostlinami, vodní systém. Slepá ulička."
     :connections ("C-arboretum"))
    (:id "C-centralni-sachta" :deck "C" :name "Centrální šachta"
     :location "Střed" :note ""
     :desc "Vertikální šachta spojující paluby B-J. Žebříky a servisní plošiny."
     :connections ("C-spolecenska" "C-osetrovna" "C-zotavovaci"
                   "C-kajuta-lekar" "C-kajuta-vedouci" "C-arboretum"
                   "B-centralni-sachta" "D-centralni-sachta" "E-centralni-sachta"
                   "F-centralni-sachta" "G-centralni-sachta" "H-centralni-sachta"
                   "I-centralni-sachta" "J-centralni-sachta"))

    ;; === Paluba D ===
    (:id "D-merici" :deck "D" :name "Měřící stanice"
     :location "Sever-střed" :note ""
     :desc "Vědecká měřící stanice. Senzory, analyzátory, datové terminály."
     :connections ("D-astro-lab" "D-kajuta-vedec"))
    (:id "D-astro-lab" :deck "D" :name "Astrofyzikální laboratoř"
     :location "Severozápad" :note ""
     :desc "Velká vědecká laboratoř. Spektrografy, teleskopická data, počítačové modely. Hlavní pracoviště pro výzkum."
     :connections ("D-merici" "D-centralni-sachta"))
    (:id "D-kajuta-vedec" :deck "D" :name "Kajuta vědeckého důstojníka"
     :location "Severovýchod" :note ""
     :desc "Soukromá kajuta a pracoviště vědce. Osobní terminál, vědecké poznámky."
     :connections ("D-merici" "D-wc"))
    (:id "D-wc" :deck "D" :name "WC"
     :location "Východ" :note ""
     :desc "Toaleta paluby D."
     :connections ("D-kajuta-vedec" "D-recepce"))
    (:id "D-kancelar-inzenyr" :deck "D" :name "Kancelář vedoucího inženýra"
     :location "Jihozápad" :note ""
     :desc "Kancelář šéfinženýra stanice. Technické výkresy, schémata systémů. Přístup k informacím o infrastruktuře."
     :connections ("D-sklad" "D-recepce"))
    (:id "D-sklad" :deck "D" :name "Sklad"
     :location "Jihozápad" :note ""
     :desc "Sklad s policemi. Vědecké potřeby, náhradní díly. Slepá ulička."
     :connections ("D-kancelar-inzenyr"))
    (:id "D-recepce" :deck "D" :name "Recepce a VIP salónek"
     :location "Jih-střed" :note ""
     :desc "Reprezentativní prostor pro příjem návštěvníků. Otevřený prostor — špatné krytí, ale přehledný."
     :connections ("D-wc" "D-kancelar-inzenyr" "D-dokovaci-port" "D-centralni-sachta"))
    (:id "D-dokovaci-port" :deck "D" :name "Návštěvnický dokovací port"
     :location "Jih" :note "Přístup do vesmíru."
     :desc "Dokovací prostor pro návštěvnické lodě. Přímý přístup do vesmíru — potenciální úniková cesta, pokud je zde loď. Zabezpečené dveře."
     :connections ("D-recepce"))
    (:id "D-centralni-sachta" :deck "D" :name "Centrální šachta"
     :location "Střed" :note ""
     :desc "Vertikální šachta spojující paluby B-J. Žebříky a servisní plošiny."
     :connections ("D-astro-lab" "D-recepce"
                   "B-centralni-sachta" "C-centralni-sachta" "E-centralni-sachta"
                   "F-centralni-sachta" "G-centralni-sachta" "H-centralni-sachta"
                   "I-centralni-sachta" "J-centralni-sachta"))

    ;; === Paluba E ===
    (:id "E-sklad" :deck "E" :name "Sklad"
     :location "Severozápad" :note ""
     :desc "Sklad zásob pro obytnou palubu. Police s potravinami a spotřebním materiálem."
     :connections ("E-kajuta-1" "E-pradelna"))
    (:id "E-pradelna" :deck "E" :name "Prádelna"
     :location "Severovýchod" :note ""
     :desc "Průmyslová prádelna. Pračky, sušičky, chemikálie. Hlučné."
     :connections ("E-sklad" "E-kajuta-2"))
    (:id "E-kajuta-1" :deck "E" :name "Kajuta 1 (levá horní)"
     :location "Západ, rada 1" :note ""
     :desc "Standardní posádková kajuta. Palanda, skříňka, malý stůl. Dá se zabarikádovat."
     :connections ("E-sklad" "E-kajuta-2" "E-kajuta-3" "E-chodba"))
    (:id "E-kajuta-2" :deck "E" :name "Kajuta 2 (pravá horní)"
     :location "Východ, rada 1" :note ""
     :desc "Standardní posádková kajuta. Palanda, skříňka, malý stůl."
     :connections ("E-pradelna" "E-kajuta-1" "E-kajuta-4" "E-chodba"))
    (:id "E-kajuta-3" :deck "E" :name "Kajuta 3 (levá střední)"
     :location "Západ, rada 2" :note ""
     :desc "Standardní posádková kajuta. Palanda, skříňka, malý stůl."
     :connections ("E-kajuta-1" "E-kajuta-4" "E-kajuta-5" "E-chodba"))
    (:id "E-kajuta-4" :deck "E" :name "Kajuta 4 (pravá střední)"
     :location "Východ, rada 2" :note ""
     :desc "Standardní posádková kajuta. Palanda, skříňka, malý stůl."
     :connections ("E-kajuta-2" "E-kajuta-3" "E-kajuta-6" "E-chodba"))
    (:id "E-kajuta-5" :deck "E" :name "Kajuta 5 (levá dolní)"
     :location "Západ, rada 3" :note ""
     :desc "Standardní posádková kajuta. Palanda, skříňka, malý stůl."
     :connections ("E-kajuta-3" "E-kajuta-6" "E-chodba"))
    (:id "E-kajuta-6" :deck "E" :name "Kajuta 6 (pravá dolní)"
     :location "Východ, rada 3" :note ""
     :desc "Standardní posádková kajuta. Palanda, skříňka, malý stůl."
     :connections ("E-kajuta-4" "E-kajuta-5" "E-chodba"))
    (:id "E-chodba" :deck "E" :name "Centrální chodba"
     :location "Střed" :note ""
     :desc "Dlouhá chodba mezi kajutami. Dveře po obou stranách, 6 kajut celkem (3+3)."
     :connections ("E-kajuta-1" "E-kajuta-2" "E-kajuta-3" "E-kajuta-4"
                   "E-kajuta-5" "E-kajuta-6" "E-jidelna" "E-centralni-sachta"))
    (:id "E-jidelna" :deck "E" :name "Jídelna"
     :location "Střed-jih" :note ""
     :desc "Velký společný stravovací prostor. Stoly, židle, výdejní pult. Otevřený prostor — přehled, ale špatné krytí."
     :connections ("E-chodba" "E-wc" "E-sprchy-z" "E-satna" "E-centralni-sachta"))
    (:id "E-wc" :deck "E" :name "WC"
     :location "Jihozápad" :note ""
     :desc "Toaleta paluby E."
     :connections ("E-jidelna" "E-sprchy-z"))
    (:id "E-sprchy-z" :deck "E" :name "Sprchy (západ)"
     :location "Jihozápad" :note ""
     :desc "Sprchový kout. Vlhko, kluzká podlaha."
     :connections ("E-wc" "E-jidelna"))
    (:id "E-satna" :deck "E" :name "Šatna a sprchy (východ)"
     :location "Jihovýchod" :note ""
     :desc "Šatna se skříňkami a sprchami. Přístup k tělocvičně."
     :connections ("E-jidelna" "E-telocvicna"))
    (:id "E-telocvicna" :deck "E" :name "Tělocvična"
     :location "Jihovýchod" :note ""
     :desc "Fitness prostor. Posilovací stroje, tyče, závaží — potenciální improvizované zbraně. Slepá ulička."
     :connections ("E-satna"))
    (:id "E-centralni-sachta" :deck "E" :name "Centrální šachta"
     :location "Střed" :note ""
     :desc "Vertikální šachta spojující paluby B-J. Žebříky a servisní plošiny. Poslední civilizovaná paluba — níž začíná věznice."
     :connections ("E-chodba" "E-jidelna"
                   "B-centralni-sachta" "C-centralni-sachta" "D-centralni-sachta"
                   "F-centralni-sachta" "G-centralni-sachta" "H-centralni-sachta"
                   "I-centralni-sachta" "J-centralni-sachta"))

    ;; === Paluba F ===
    (:id "F-centralni-sachta" :deck "F" :name "Centrální šachta"
     :location "Sever (vrch paluby)" :note "Šachta navrchu, chodba vede ke zbrojnici."
     :desc "Šachta na vrchu vězeňské paluby. Vstup do hlavní chodby na jihu."
     :connections ("F-chodba"
                   "B-centralni-sachta" "C-centralni-sachta" "D-centralni-sachta"
                   "E-centralni-sachta" "G-centralni-sachta" "H-centralni-sachta"
                   "I-centralni-sachta" "J-centralni-sachta"))
    (:id "F-chodba" :deck "F" :name "Centrální chodba"
     :location "Střed (celá paluba)" :note ""
     :desc "Hlavní koridor vězeňské paluby od centrální šachty až k celám. Zbrojnice, kuchyně, sklady a WC po stranách za dveřmi. Průlezy F1, F2, F5, F6 v podlaze vedou na palubu G."
     :connections ("F-centralni-sachta" "F-zbrojnice" "F-kuchyne"
                   "F-sklad-z" "F-sklad-v" "F-wc-z" "F-wc-v"
                   "F-sprchy-z" "F-sprchy-v" "F-cely-z" "F-cely-v" "F-sklady-jih"
                   "G-nakladovy-dok" "G-opravarensky-dok" "G-hangar-01" "G-hangar-02"))
    (:id "F-zbrojnice" :deck "F" :name "Zbrojnice"
     :location "Sever-střed" :note "ZBRANE."
     :desc "ZBROJNICE — uzamčená místnost se zbraněmi. Pušky, pistole, munice, výstroj. Klíčové místo na celé stanici."
     :connections ("F-chodba" "F-vezenska-sluzba" "F-priprava-stravy"))
    (:id "F-kuchyne" :deck "F" :name "Kuchyně"
     :location "Střed-sever" :note ""
     :desc "Vězeňská kuchyně. Průmyslové vybavení na přípravu jídla pro vězně. Nože a náčiní."
     :connections ("F-chodba"))
    (:id "F-vezenska-sluzba" :deck "F" :name "Vězeňská služba"
     :location "Severozápad" :note ""
     :desc "Kanceláře vězeňského personálu. Monitorovací panely, komunikační systém, klíče."
     :connections ("F-zbrojnice" "F-udrzba-androidu"))
    (:id "F-priprava-stravy" :deck "F" :name "Příprava stravy"
     :location "Severovýchod" :note ""
     :desc "Přípravna jídla pro vězeňský komplex. Velké sporáky, pracovní plochy."
     :connections ("F-zbrojnice" "F-osetrovna" "F-pradelna"))
    (:id "F-udrzba-androidu" :deck "F" :name "Údržba androidů"
     :location "Západ" :note ""
     :desc "Servisní dílna pro androidy. Diagnostické nástroje, náhradní díly. Možnost opravy nebo reprogramování androidů."
     :connections ("F-vezenska-sluzba" "F-sprchy-z" "F-sklad-z"))
    (:id "F-osetrovna" :deck "F" :name "Ošetřovna"
     :location "Východ" :note ""
     :desc "Vězeňská ošetřovna. Základní lékařské vybavení, lůžko, lékárnička."
     :connections ("F-priprava-stravy" "F-pradelna"))
    (:id "F-pradelna" :deck "F" :name "Prádelna"
     :location "Východ" :note ""
     :desc "Vězeňská prádelna. Průmyslové pračky, chemikálie na praní."
     :connections ("F-priprava-stravy" "F-osetrovna" "F-sprchy-v" "F-sklad-v"))
    (:id "F-sprchy-z" :deck "F" :name "Sprchy (západ)"
     :location "Krajní západ" :note ""
     :desc "Vězeňské sprchy, západní sekce. Otevřený prostor, kluzká podlaha."
     :connections ("F-udrzba-androidu" "F-chodba"))
    (:id "F-sprchy-v" :deck "F" :name "Sprchy (východ)"
     :location "Krajní východ" :note ""
     :desc "Vězeňské sprchy, východní sekce. Otevřený prostor, kluzká podlaha."
     :connections ("F-pradelna" "F-chodba"))
    (:id "F-sklad-z" :deck "F" :name "Sklad (západ)"
     :location "Střed-západ" :note ""
     :desc "Sklad západní sekce. Police se zásobami."
     :connections ("F-chodba" "F-udrzba-androidu" "F-wc-z"))
    (:id "F-sklad-v" :deck "F" :name "Sklad (východ)"
     :location "Střed-východ" :note ""
     :desc "Sklad východní sekce. Police se zásobami."
     :connections ("F-chodba" "F-pradelna" "F-wc-v"))
    (:id "F-wc-z" :deck "F" :name "WC (západ)"
     :location "Střed-západ" :note ""
     :desc "Toaleta západní sekce."
     :connections ("F-sklad-z" "F-chodba"))
    (:id "F-wc-v" :deck "F" :name "WC (východ)"
     :location "Střed-východ" :note ""
     :desc "Toaleta východní sekce."
     :connections ("F-sklad-v" "F-chodba"))
    (:id "F-cely-z" :deck "F" :name "Cely (západ)"
     :location "Jihozápad" :note ""
     :desc "Západní celový blok. Řady zamřížovaných cel. Vězni mohou být spojenci i hrozby. Průlez F7 v podlaze vede na palubu G."
     :connections ("F-chodba" "F-sklady-jih" "G-nakladovy-dok"))
    (:id "F-cely-v" :deck "F" :name "Cely (východ)"
     :location "Jihovýchod" :note ""
     :desc "Východní celový blok. Řady zamřížovaných cel. Průlez F8 v podlaze vede na palubu G."
     :connections ("F-chodba" "F-sklady-jih" "G-opravarensky-dok"))
    (:id "F-sklady-jih" :deck "F" :name "Sklady (jih, 4 kusy)"
     :location "Jih-střed" :note ""
     :desc "Čtyři skladové místnosti v jižní části. Mohou obsahovat zásoby, materiál, nebo skrýše."
     :connections ("F-chodba" "F-cely-z" "F-cely-v"))

    ;; === Paluba G ===
    (:id "G-shromazdiste" :deck "G" :name "Nouzové shromaždiště"
     :location "Sever" :note ""
     :desc "Velký prostor pro nouzovou evakuaci. Sem se sbíhá posádka při poplachu. Přístup ke komunikační věži."
     :connections ("G-nastupni-hala" "GH-komunikacni-vez"))
    (:id "G-nastupni-hala" :deck "G" :name "Nástupní hala"
     :location "Sever-střed" :note ""
     :desc "Centrální hala paluby G. Rozcestí k hangárům, EVA podům, šachtě. Průlezy G3/G4 v podlaze vedou na palubu H k nádrži toxických plynů."
     :connections ("G-shromazdiste"
                   "G-eva-sz" "G-eva-sv" "G-servis-androidu" "G-centralni-sachta"
                   "H-nadrz-toxickych"))
    (:id "G-hangar-01" :deck "G" :name "Hangár 01"
     :location "Západ" :note ""
     :desc "Velký hangár pro menší plavidla. Vysoký strop, nákladní vrata. Průlez G5 vede nahoru na palubu F."
     :connections ("G-dokovaci-01" "G-sklady-z" "F-chodba"))
    (:id "G-dokovaci-01" :deck "G" :name "Dokovací port 01"
     :location "Krajní západ" :note "Přístup do vesmíru."
     :desc "Zabezpečený dokovací port. Přímý přístup do vesmíru — vzduchová komora. Slepá ulička."
     :connections ("G-hangar-01"))
    (:id "G-hangar-02" :deck "G" :name "Hangár 02"
     :location "Východ" :note ""
     :desc "Velký hangár pro menší plavidla. Vysoký strop, nákladní vrata. Průlez G6 vede nahoru na palubu F."
     :connections ("G-dokovaci-02" "G-sklady-v" "F-chodba"))
    (:id "G-dokovaci-02" :deck "G" :name "Dokovací port 02"
     :location "Krajní východ" :note "Přístup do vesmíru."
     :desc "Zabezpečený dokovací port. Přímý přístup do vesmíru — vzduchová komora. Slepá ulička."
     :connections ("G-hangar-02"))
    (:id "G-eva-sz" :deck "G" :name "EVA pod (SZ)"
     :location "Střed-SZ" :note ""
     :desc "Stanice pro výstup do kosmu. Skafandry, kyslíkové lahve, bezpečnostní lana."
     :connections ("G-nastupni-hala" "G-servis-androidu"))
    (:id "G-eva-sv" :deck "G" :name "EVA pod (SV)"
     :location "Střed-SV" :note ""
     :desc "Stanice pro výstup do kosmu. Skafandry a vybavení pro EVA."
     :connections ("G-nastupni-hala" "G-servis-androidu"))
    (:id "G-eva-jz" :deck "G" :name "EVA pod (JZ)"
     :location "Střed-JZ" :note ""
     :desc "Stanice pro výstup do kosmu. Skafandry a EVA vybavení."
     :connections ("G-servis-androidu" "G-kryopody-z"))
    (:id "G-eva-jv" :deck "G" :name "EVA pod (JV)"
     :location "Střed-JV" :note ""
     :desc "Stanice pro výstup do kosmu. Skafandry a EVA vybavení."
     :connections ("G-servis-androidu" "G-kryopody-v"))
    (:id "G-sklady-z" :deck "G" :name "Sklady (západ)"
     :location "Západ" :note ""
     :desc "Rozlehlé sklady u hangáru 01. Náhradní díly, palivo, náklad."
     :connections ("G-hangar-01" "G-centralni-sachta"))
    (:id "G-sklady-v" :deck "G" :name "Sklady (východ)"
     :location "Východ" :note ""
     :desc "Rozlehlé sklady u hangáru 02. Náhradní díly, palivo, náklad."
     :connections ("G-hangar-02" "G-centralni-sachta"))
    (:id "G-servis-androidu" :deck "G" :name "Servisní úložiště androidů"
     :location "Střed" :note ""
     :desc "Sklad a servis androidů. Nabíjecí stanice, diagnostika, náhradní díly. Centrální pozice — přístup ke všem EVA podům."
     :connections ("G-nastupni-hala" "G-eva-sz" "G-eva-sv"
                   "G-eva-jz" "G-eva-jv" "G-centralni-sachta"))
    (:id "G-nakladovy-dok" :deck "G" :name "Nákladový dok"
     :location "Jihozápad" :note ""
     :desc "Dok pro nakládání a vykládání nákladu. Jeřáby, palety, kontejnery. Průlezy G1/G7 — nahoru na palubu F, dolů na H."
     :connections ("G-kryopody-z" "F-chodba" "F-cely-z" "H-plasma-jz"))
    (:id "G-opravarensky-dok" :deck "G" :name "Opravárenský dok"
     :location "Jihovýchod" :note ""
     :desc "Dok pro opravy plavidel. Svářečky, nářadí, diagnostické přístroje. Průlezy G2/G8 — nahoru na palubu F, dolů na H."
     :connections ("G-kryopody-v" "F-chodba" "F-cely-v" "H-plasma-jv"))
    (:id "G-kryopody-z" :deck "G" :name "Nouzové kryopody (Z)"
     :location "Jihozápad" :note ""
     :desc "Řada nouzových kryogenních lůžek. Nouzový kryospánek — útočiště poslední instance."
     :connections ("G-eva-jz" "G-nakladovy-dok"))
    (:id "G-kryopody-v" :deck "G" :name "Nouzové kryopody (V)"
     :location "Jihovýchod" :note ""
     :desc "Řada nouzových kryogenních lůžek. Záložní kryospánek."
     :connections ("G-eva-jv" "G-opravarensky-dok"))
    (:id "G-centralni-sachta" :deck "G" :name "Centrální šachta"
     :location "Střed" :note ""
     :desc "Vertikální šachta spojující paluby B-J. Žebříky a servisní plošiny. Rozlehlá paluba — přesuny trvají déle."
     :connections ("G-nastupni-hala" "G-sklady-z" "G-sklady-v" "G-servis-androidu"
                   "B-centralni-sachta" "C-centralni-sachta" "D-centralni-sachta"
                   "E-centralni-sachta" "F-centralni-sachta" "H-centralni-sachta"
                   "I-centralni-sachta" "J-centralni-sachta"))

    ;; === Komunikacni vez (G/H) ===
    (:id "GH-komunikacni-vez" :deck "GH" :name "Komunikační věž / DA/UT/UR"
     :location "Mezi G a H" :note "Komunikační počítač (Daughter)."
     :desc "Vertikální věž s komunikačním počítačem DA/UT/UR (Daughter). Úzká — snadno bránitelná, ale i past. Alternativa k MU/TH/UR na palubě B."
     :connections ("G-shromazdiste" "H-ridici-centrum"))

    ;; === Paluba H ===
    (:id "H-plasma-sz" :deck "H" :name "Plasmová stanice (SZ)"
     :location "Severozápad" :note ""
     :desc "Průmyslová plasmová přenosová stanice. Horko, hluk, vysoké napětí. Poškození hrozí energetickou katastrofou."
     :connections ("H-nadrz-toxickych" "H-destilacni-z"))
    (:id "H-plasma-sv" :deck "H" :name "Plasmová stanice (SV)"
     :location "Severovýchod" :note ""
     :desc "Průmyslová plasmová přenosová stanice. Horko, hluk, vysoké napětí."
     :connections ("H-nadrz-toxickych" "H-destilacni-v"))
    (:id "H-nadrz-toxickych" :deck "H" :name "Nádrž toxických plynů"
     :location "Sever-střed" :note "NEBEZPEČNÉ — unik = smrt."
     :desc "EXTRÉMNĚ NEBEZPEČNÉ. Obrovská nádrž s jedovatými plyny. Únik znamená smrt na celé palubě. Průlezy H3/H4 vedou nahoru na palubu G."
     :connections ("H-plasma-sz" "H-plasma-sv" "G-nastupni-hala"))
    (:id "H-destilacni-z" :deck "H" :name "Destilační nádrže (Z)"
     :location "Západ" :note ""
     :desc "Velké chemické destilační nádrže. Potrubí, ventily, tlakové manometry."
     :connections ("H-plasma-sz" "H-kondenzatory-z"))
    (:id "H-destilacni-v" :deck "H" :name "Destilační nádrže (V)"
     :location "Východ" :note ""
     :desc "Velké chemické destilační nádrže. Potrubí, ventily, tlakové manometry."
     :connections ("H-plasma-sv" "H-kondenzatory-v"))
    (:id "H-kondenzatory-z" :deck "H" :name "Kondenzátory (Z)"
     :location "Západ" :note ""
     :desc "Průmyslové kondenzátory. Kovové povrchy, chladící systém, hluk."
     :connections ("H-destilacni-z" "H-sberac-01" "H-dilny-z"))
    (:id "H-kondenzatory-v" :deck "H" :name "Kondenzátory (V)"
     :location "Východ" :note ""
     :desc "Průmyslové kondenzátory. Kovové povrchy, chladící systém, hluk."
     :connections ("H-destilacni-v" "H-sberac-02" "H-dilny-v"))
    (:id "H-sberac-01" :deck "H" :name "Plasmový sběrač 01"
     :location "Krajní západ" :note ""
     :desc "Masivní plasmový sběrač na kraji paluby. Kritická infrastruktura. Slepá ulička."
     :connections ("H-kondenzatory-z"))
    (:id "H-sberac-02" :deck "H" :name "Plasmový sběrač 02"
     :location "Krajní východ" :note ""
     :desc "Masivní plasmový sběrač na kraji paluby. Kritická infrastruktura. Slepá ulička."
     :connections ("H-kondenzatory-v"))
    (:id "H-dilny-z" :deck "H" :name "Dílny (Z)"
     :location "Střed-západ" :note "Nářadí."
     :desc "Dílna s nářadím — klíče, svářečky, řezné nástroje. Improvizované zbraně. Dobrý zdroj vybavení."
     :connections ("H-kondenzatory-z" "H-ridici-centrum"))
    (:id "H-dilny-v" :deck "H" :name "Dílny (V)"
     :location "Střed-východ" :note "Nářadí."
     :desc "Dílna s nářadím — klíče, svářečky, řezné nástroje. Zrcadlová kopie západních dílen."
     :connections ("H-kondenzatory-v" "H-ridici-centrum"))
    (:id "H-ridici-centrum" :deck "H" :name "Řídící centrum"
     :location "Střed" :note ""
     :desc "Řídící centrum průmyslové paluby. Konzole pro ovládání tavení, plasmy, destilace. Možnost sabotáže nebo nouzového vypnutí."
     :connections ("H-dilny-z" "H-dilny-v" "H-strojovna-z" "H-strojovna-v" "H-centralni-sachta" "GH-komunikacni-vez"))
    (:id "H-strojovna-z" :deck "H" :name "Strojovna (Z)"
     :location "Jih-západ" :note ""
     :desc "Těžké strojní vybavení. Hlučné, horké, špatná viditelnost od páry."
     :connections ("H-ridici-centrum" "H-mag-cerpadlo"))
    (:id "H-strojovna-v" :deck "H" :name "Strojovna (V)"
     :location "Jih-východ" :note ""
     :desc "Těžké strojní vybavení. Hlučné, horké, špatná viditelnost."
     :connections ("H-ridici-centrum" "H-mag-cerpadlo"))
    (:id "H-mag-cerpadlo" :deck "H" :name "Magnetické čerpadlo"
     :location "Jih-střed" :note ""
     :desc "Velké magnetické čerpadlo pro přesun materiálu. Silné elektromagnetické pole — pozor na elektroniku."
     :connections ("H-strojovna-z" "H-strojovna-v" "H-taveni"))
    (:id "H-taveni" :deck "H" :name "Řídící stanice tavení"
     :location "Jih-střed" :note ""
     :desc "Řízení tavicího procesu. Vysoké teploty v okolí, ochranné štíty."
     :connections ("H-mag-cerpadlo" "H-plasma-jz" "H-plasma-jv"))
    (:id "H-plasma-jz" :deck "H" :name "Plasmová stanice (JZ)"
     :location "Jihozápad" :note ""
     :desc "Jižní plasmová přenosová stanice. Horko, hluk, nebezpečí popálenin. Průlez H7 vede nahoru na palubu G."
     :connections ("H-taveni" "H-energie-z" "G-nakladovy-dok"))
    (:id "H-plasma-jv" :deck "H" :name "Plasmová stanice (JV)"
     :location "Jihovýchod" :note ""
     :desc "Jižní plasmová přenosová stanice. Horko, hluk, nebezpečí popálenin. Průlez H8 vede nahoru na palubu G."
     :connections ("H-taveni" "H-energie-v" "G-opravarensky-dok"))
    (:id "H-energie-z" :deck "H" :name "Energetické sběrné články (Z)"
     :location "Krajní jihozápad" :note ""
     :desc "Zásobníky energie na okraji paluby. Kritická infrastruktura stanice. Slepá ulička."
     :connections ("H-plasma-jz"))
    (:id "H-energie-v" :deck "H" :name "Energetické sběrné články (V)"
     :location "Krajní jihovýchod" :note ""
     :desc "Zásobníky energie na okraji paluby. Kritická infrastruktura. Slepá ulička."
     :connections ("H-plasma-jv"))
    (:id "H-centralni-sachta" :deck "H" :name "Centrální šachta"
     :location "Střed" :note ""
     :desc "Vertikální šachta na NEJVĚTŠÍ palubě stanice (měřítko 10 m). Žebříky a servisní plošiny. Průmyslový hluk ze všech stran."
     :connections ("H-ridici-centrum"
                   "B-centralni-sachta" "C-centralni-sachta" "D-centralni-sachta"
                   "E-centralni-sachta" "F-centralni-sachta" "G-centralni-sachta"
                   "I-centralni-sachta" "J-centralni-sachta"))

    ;; === Paluba I ===
    (:id "I-zachranne-moduly" :deck "I" :name "Záchranné moduly"
     :location "Celá paluba" :note "Únikové kapsle."
     :desc "Paluba se záchrannými moduly — únikové kapsle pro evakuaci posádky. Zjisti od GM, kolik kapslí je funkčních."
     :connections ("I-centralni-sachta"))
    (:id "I-centralni-sachta" :deck "I" :name "Centrální šachta"
     :location "Střed" :note ""
     :desc "Vertikální šachta. Pod touto palubou je už jen strojovna reaktoru (J)."
     :connections ("I-zachranne-moduly"
                   "B-centralni-sachta" "C-centralni-sachta" "D-centralni-sachta"
                   "E-centralni-sachta" "F-centralni-sachta" "G-centralni-sachta"
                   "H-centralni-sachta" "J-centralni-sachta"))

    ;; === Paluba J ===
    (:id "J-baterie-horni" :deck "J" :name "Baterie (horní)"
     :location "Sever-střed" :note ""
     :desc "Velká energetická baterie reaktoru. Hučení, vibrace. Poškození může vést k explozi nebo výpadku energie."
     :connections ("J-centralni-sachta"))
    (:id "J-baterie-leva" :deck "J" :name "Baterie (západ)"
     :location "Západ" :note ""
     :desc "Energetická baterie reaktoru, západní pozice. Hučení, vibrace. Slepá ulička."
     :connections ("J-centralni-sachta"))
    (:id "J-baterie-prava" :deck "J" :name "Baterie (východ)"
     :location "Východ" :note ""
     :desc "Energetická baterie reaktoru, východní pozice. Hučení, vibrace. Slepá ulička."
     :connections ("J-centralni-sachta"))
    (:id "J-centralni-sachta" :deck "J" :name "Centrální šachta"
     :location "Střed" :note "Nejnižší paluba — jen nahoru."
     :desc "Nejnižší bod stanice. Srdce reaktoru — tři baterie kolem. Odtud vede cesta jen nahoru. Nouzový protokol zničení stanice by začal zde."
     :connections ("J-baterie-horni" "J-baterie-leva" "J-baterie-prava"
                   "B-centralni-sachta" "C-centralni-sachta" "D-centralni-sachta"
                   "E-centralni-sachta" "F-centralni-sachta" "G-centralni-sachta"
                   "H-centralni-sachta" "I-centralni-sachta")))
  "Kompletní seznam místností. Ověřeno z PDF map.")

;; ====================================================================
;; POSTAVA
;; ====================================================================

(defvar alien-rpg-character
  '(:name "prof. Héctor Navarre"
    :career "biochemický inženýr"
    :age 74
    :attributes (:strength 3 :agility 4 :wits 3 :empathy 4)
    :skills (:close-combat 2 :heavy-machinery 2 :stamina 0
             :mobility 0 :piloting 0 :ranged-combat 3
             :comtech 0 :observation 2 :survival 0
             :command 0 :manipulation 3 :medical-aid 0)
    :talent "Analýza: Hod na OBSERVATION, za každý úspěch informace o mimozemském organismu nebo předmětu."
    :gear ("svítilna" "CBRN detektor (viry, toxiny, radiace)" "lokátor PDT")
    :signature-item "karta")
  "Statická data postavy.")

(defvar alien-rpg-skill-attributes
  '((:close-combat . :strength)  (:heavy-machinery . :strength) (:stamina . :strength)
    (:mobility . :agility)       (:piloting . :agility)         (:ranged-combat . :agility)
    (:comtech . :wits)           (:observation . :wits)         (:survival . :wits)
    (:command . :empathy)        (:manipulation . :empathy)     (:medical-aid . :empathy))
  "Mapování dovedností na atributy.")

(defvar alien-rpg-skill-names
  '((:close-combat . "Close Combat") (:heavy-machinery . "Heavy Machinery")
    (:stamina . "Stamina") (:mobility . "Mobility") (:piloting . "Piloting")
    (:ranged-combat . "Ranged Combat") (:comtech . "Comtech")
    (:observation . "Observation") (:survival . "Survival")
    (:command . "Command") (:manipulation . "Manipulation")
    (:medical-aid . "Medical Aid"))
  "Názvy dovedností.")

(defvar alien-rpg-attr-abbrevs
  '((:strength . "Str") (:agility . "Agi") (:wits . "Wit") (:empathy . "Emp"))
  "Zkratky atributů.")

;; ====================================================================
;; STAV HRY
;; ====================================================================

(defvar alien-rpg-state
  '(:health 4
    :stress 0
    :resolve 4
    :current-room "B-centralni-sachta"
    :weapons ()
    :armor nil
    :extra-gear ()
    :tiny-items ()
    :injuries ()
    :conditions ()
    :story-points 0
    :notes ()
    :room-notes nil)
  "Dynamický herní stav.")

(defvar alien-rpg-state-file
  (expand-file-name "alien-rpg-save.el"
                    (file-name-directory (or load-file-name
                                             buffer-file-name
                                             "~/alienrpg/")))
  "Soubor pro ukládání.")

;; ====================================================================
;; POMOCNE FUNKCE
;; ====================================================================

(defun alien-rpg--get-room (room-id)
  "Najdi místnost podle ROOM-ID."
  (cl-find-if (lambda (r) (string= (plist-get r :id) room-id))
              alien-rpg-rooms))

(defun alien-rpg--get-deck (deck-id)
  "Najdi palubu podle DECK-ID."
  (cl-find-if (lambda (d) (string= (plist-get d :id) deck-id))
              alien-rpg-decks))

(defun alien-rpg--room-label (room)
  "Kód a jméno: B-mu-th-ur MU/TH/UR"
  (format "%s %s" (plist-get room :id) (plist-get room :name)))

(defun alien-rpg--current-room ()
  "Aktuální místnost."
  (alien-rpg--get-room (plist-get alien-rpg-state :current-room)))

(defun alien-rpg--connected-rooms (room)
  "Propojené místnosti."
  (cl-remove-if #'null
                (mapcar #'alien-rpg--get-room (plist-get room :connections))))

(defun alien-rpg--rooms-on-deck (deck-id)
  "Všechny místnosti na palubě."
  (cl-remove-if-not
   (lambda (r) (string= (plist-get r :deck) deck-id))
   alien-rpg-rooms))

(defun alien-rpg--sort-candidates (candidates)
  "Seřaď alist CANDIDATES abecedně podle car."
  (sort (copy-sequence candidates) (lambda (a b) (string< (car a) (car b)))))

(defun alien-rpg--room-notes (room-id)
  "Poznámky k místnosti ROOM-ID."
  (cdr (assoc room-id (plist-get alien-rpg-state :room-notes))))

(defun alien-rpg--output (title &rest body-fn)
  "Výstup do *Alien RPG* bufferu s alien-rpg-view-mode."
  (with-current-buffer (get-buffer-create "*Alien RPG*")
    (let ((inhibit-read-only t))
      (erase-buffer)
      (dolist (fn body-fn)
        (funcall fn)))
    (goto-char (point-min))
    (alien-rpg-view-mode))
  (switch-to-buffer "*Alien RPG*"))

(defun alien-rpg--skill-total (skill-key)
  "Celkový počet (atribut + dovednost)."
  (let* ((attrs (plist-get alien-rpg-character :attributes))
         (skills (plist-get alien-rpg-character :skills))
         (attr-key (cdr (assq skill-key alien-rpg-skill-attributes)))
         (attr-val (or (plist-get attrs attr-key) 0))
         (skill-val (or (plist-get skills skill-key) 0)))
    (+ attr-val skill-val)))

(defun alien-rpg--find-all-shortest-paths (start goal)
  "Najdi všechny nejkratší cesty z START do GOAL."
  (let ((queue (list (list start)))
        (visited (make-hash-table :test 'equal))
        (found-paths nil)
        (found-dist most-positive-fixnum))
    (puthash start 0 visited)
    (while queue
      (let* ((path (pop queue))
             (current (car (last path)))
             (dist (1- (length path))))
        (when (> dist found-dist)
          (setq queue nil))
        (when (<= dist found-dist)
          (if (string= current goal)
              (progn
                (setq found-dist dist)
                (push path found-paths))
            (let ((room (alien-rpg--get-room current)))
              (when room
                (dolist (next (plist-get room :connections))
                  (let ((new-dist (1+ dist)))
                    (when (<= new-dist found-dist)
                      (let ((prev (gethash next visited)))
                        (when (or (null prev) (>= prev new-dist))
                          (puthash next new-dist visited)
                          (setq queue (append queue (list (append path (list next))))))))))))))))
    (nreverse found-paths)))

;; ====================================================================
;; ULOZENI / NACTENI
;; ====================================================================

(defun alien-rpg-save-state ()
  "Ulož herní stav."
  (interactive)
  (let ((file alien-rpg-state-file))
    (with-temp-file file
      (insert ";; Alien RPG — ulozeny herni stav\n")
      (insert (format ";; %s\n" (format-time-string "%Y-%m-%d %H:%M")))
      (insert "(setq alien-rpg-state\n  '")
      (pp alien-rpg-state (current-buffer))
      (insert ")\n"))
    (message "Uloženo: %s" file)))

(defun alien-rpg-load-state ()
  "Načti herní stav."
  (interactive)
  (let ((file (or alien-rpg-state-file
                  (read-file-name "Načíst ze souboru: " nil nil t "alien-rpg-save.el"))))
    (when (file-exists-p file)
      (load file nil 'nomessage)
      (setq alien-rpg-state-file file)
      ;; Zpětná kompatibilita — doplnit chybějící klíče
      (unless (plist-member alien-rpg-state :conditions)
        (setq alien-rpg-state (plist-put alien-rpg-state :conditions nil)))
      (unless (plist-member alien-rpg-state :armor)
        (setq alien-rpg-state (plist-put alien-rpg-state :armor nil)))
      (unless (plist-member alien-rpg-state :resolve)
        (setq alien-rpg-state (plist-put alien-rpg-state :resolve 4)))
      (unless (plist-member alien-rpg-state :tiny-items)
        (setq alien-rpg-state (plist-put alien-rpg-state :tiny-items nil)))
      (unless (plist-member alien-rpg-state :room-notes)
        (setq alien-rpg-state (plist-put alien-rpg-state :room-notes nil)))
      (message "Načteno: %s" file))))

(defun alien-rpg--autosave ()
  "Automaticky ulož (tiše)."
  (when alien-rpg-state-file
    (with-temp-file alien-rpg-state-file
      (insert ";; Alien RPG — ulozeny herni stav\n")
      (insert (format ";; %s\n" (format-time-string "%Y-%m-%d %H:%M")))
      (insert "(setq alien-rpg-state\n  '")
      (pp alien-rpg-state (current-buffer))
      (insert ")\n"))))

;; Automaticky nacti stav pri startu
(when (and alien-rpg-state-file (file-exists-p alien-rpg-state-file))
  (load alien-rpg-state-file nil 'nomessage))

;; ====================================================================
;; INTERAKTIVNI PRIKAZY
;; ====================================================================

(defun alien-rpg--insert-room-info (room)
  "Vlož informace o místnosti ROOM do aktuálního bufferu."
  (let* ((deck (alien-rpg--get-deck (plist-get room :deck)))
         (my-deck (plist-get room :deck))
         (connected (alien-rpg--connected-rooms room))
         (same-deck (cl-remove-if-not
                     (lambda (r) (string= (plist-get r :deck) my-deck))
                     connected))
         (shaft-rooms (cl-remove-if-not
                       (lambda (r) (string-match-p "centralni-sachta"
                                                   (plist-get r :id)))
                       connected))
         (cross-deck (cl-remove-if
                      (lambda (r) (or (string= (plist-get r :deck) my-deck)
                                      (string-match-p "centralni-sachta"
                                                      (plist-get r :id))))
                      connected)))
    (insert (format "%s [%s]\n" (plist-get room :name) (plist-get room :id)))
    (insert (format "Paluba %s: %s, %s\n"
                    (plist-get deck :id) (plist-get deck :name) (plist-get room :location)))
    (when (plist-get room :desc)
      (insert (format "%s\n" (plist-get room :desc))))
    (let ((rnotes (alien-rpg--room-notes (plist-get room :id))))
      (when rnotes
        (insert "Poznámky:\n")
        (dolist (rn rnotes)
          (insert (format "  %s\n" rn)))))
    (when same-deck
      (insert (format "Východy: %s\n"
                      (mapconcat (lambda (r)
                                   (format "%s [%s]"
                                           (plist-get r :name)
                                           (plist-get r :id)))
                                 same-deck ", "))))
    (when cross-deck
      (insert (format "Průchody: %s\n"
                      (mapconcat (lambda (r)
                                   (let ((d (alien-rpg--get-deck (plist-get r :deck))))
                                     (format "%s [%s] (paluba %s)"
                                             (plist-get r :name)
                                             (plist-get r :id)
                                             (if d (plist-get d :id) (plist-get r :deck)))))
                                 cross-deck ", "))))
    (when shaft-rooms
      (let ((deck-ids (cl-remove-duplicates
                       (mapcar (lambda (r) (plist-get r :deck)) shaft-rooms)
                       :test #'string=)))
        (insert (format "Šachta: %s\n"
                        (mapconcat (lambda (did)
                                     (let ((d (alien-rpg--get-deck did)))
                                       (if d
                                           (format "%s %s" did (plist-get d :name))
                                         did)))
                                   deck-ids ", ")))))))

(defun alien-rpg-where-am-i ()
  "Kde jsem — popis pro screen reader."
  (interactive)
  (let ((room (alien-rpg--current-room)))
    (with-current-buffer (get-buffer-create "*Alien RPG*")
      (let ((inhibit-read-only t))
        (erase-buffer)
        (alien-rpg--insert-room-info room))
      (goto-char (point-min))
      (alien-rpg-view-mode))
    (switch-to-buffer "*Alien RPG*")))

(defun alien-rpg-move ()
  "Přesun do propojené místnosti."
  (interactive)
  (let* ((room (alien-rpg--current-room))
         (connected (alien-rpg--connected-rooms room))
         (candidates (alien-rpg--sort-candidates
                      (mapcar (lambda (r)
                                (cons (alien-rpg--room-label r) (plist-get r :id)))
                              connected)))
         (choice (completing-read
                  (format "%s -> " (plist-get room :id))
                  candidates nil t))
         (target-id (cdr (assoc choice candidates))))
    (setq alien-rpg-state (plist-put alien-rpg-state :current-room target-id))
    (alien-rpg--autosave)
    (alien-rpg-where-am-i)))

(defun alien-rpg-teleport ()
  "Teleport kamkoliv."
  (interactive)
  (let* ((candidates (alien-rpg--sort-candidates
                      (mapcar (lambda (r)
                                (cons (alien-rpg--room-label r) (plist-get r :id)))
                              alien-rpg-rooms)))
         (choice (completing-read "Teleport: " candidates nil t))
         (target-id (cdr (assoc choice candidates))))
    (setq alien-rpg-state (plist-put alien-rpg-state :current-room target-id))
    (alien-rpg--autosave)
    (alien-rpg-where-am-i)))

(defun alien-rpg-find-room ()
  "Info o místnosti."
  (interactive)
  (let* ((candidates (alien-rpg--sort-candidates
                      (mapcar (lambda (r)
                                (cons (alien-rpg--room-label r) r))
                              alien-rpg-rooms)))
         (choice (completing-read "Místnost: " candidates nil t))
         (room (cdr (assoc choice candidates))))
    (with-current-buffer (get-buffer-create "*Alien RPG*")
      (let ((inhibit-read-only t))
        (erase-buffer)
        (alien-rpg--insert-room-info room))
      (goto-char (point-min))
      (alien-rpg-view-mode))
    (switch-to-buffer "*Alien RPG*")))

(defun alien-rpg-find-path ()
  "Všechny nejkratší cesty do cíle."
  (interactive)
  (let* ((start (plist-get alien-rpg-state :current-room))
         (start-room (alien-rpg--get-room start))
         (candidates (alien-rpg--sort-candidates
                      (mapcar (lambda (r)
                                (cons (alien-rpg--room-label r) (plist-get r :id)))
                              alien-rpg-rooms)))
         (choice (completing-read "Cesta do: " candidates nil t))
         (goal (cdr (assoc choice candidates)))
         (goal-room (alien-rpg--get-room goal))
         (paths (alien-rpg--find-all-shortest-paths start goal)))
    (with-current-buffer (get-buffer-create "*Alien RPG*")
      (let ((inhibit-read-only t))
        (erase-buffer)
        (if paths
            (let ((dist (1- (length (car paths))))
                  (count (min 10 (length paths))))
              (insert (format "%s -> %s: %d krok%s"
                              (plist-get start-room :name)
                              (plist-get goal-room :name)
                              dist
                              (cond ((= dist 1) "") ((< dist 5) "y") (t "ů"))))
              (when (> (length paths) 1)
                (insert (format " (%d cest)" (length paths))))
              (insert "\n\n")
              (cl-loop for path in paths
                       for i from 1 to count do
                       (when (> count 1)
                         (insert (format "Cesta %d:\n" i)))
                       (dolist (step path)
                         (let ((r (alien-rpg--get-room step)))
                           (insert (format "  - %s [%s]\n"
                                           (if r (plist-get r :name) step)
                                           step))))
                       (insert "\n")))
          (insert "Cesta nenalezena.\n")))
      (goto-char (point-min))
      (alien-rpg-view-mode))
    (switch-to-buffer "*Alien RPG*")))

(defun alien-rpg-deck-overview ()
  "Přehled paluby."
  (interactive)
  (let* ((candidates (alien-rpg--sort-candidates
                      (mapcar (lambda (d)
                                (cons (format "%s %s" (plist-get d :id) (plist-get d :name))
                                      (plist-get d :id)))
                              alien-rpg-decks)))
         (choice (completing-read "Paluba: " candidates nil t))
         (deck-id (cdr (assoc choice candidates)))
         (deck (alien-rpg--get-deck deck-id))
         (rooms (alien-rpg--rooms-on-deck deck-id)))
    (with-current-buffer (get-buffer-create "*Alien RPG*")
      (let ((inhibit-read-only t))
        (erase-buffer)
        (insert (format "[%s] %s | %s\n"
                        deck-id (plist-get deck :name) (plist-get deck :scale)))
        (dolist (r rooms)
          (insert (format "  %-25s %-35s %s\n"
                          (plist-get r :id)
                          (plist-get r :name)
                          (plist-get r :location)))))
      (goto-char (point-min))
      (alien-rpg-view-mode))
    (switch-to-buffer "*Alien RPG*")))

(defun alien-rpg-station-overview ()
  "Přehled stanice."
  (interactive)
  (let ((current-deck (plist-get (alien-rpg--current-room) :deck)))
    (with-current-buffer (get-buffer-create "*Alien RPG*")
      (let ((inhibit-read-only t))
        (erase-buffer)
        (insert (format "%s\n" alien-rpg-station-name))
        (dolist (d alien-rpg-decks)
          (let* ((id (plist-get d :id))
                 (here (string= id current-deck))
                 (marker (if here "> " "  ")))
            (insert (format "%s%s  %s\n" marker id (plist-get d :name)))
            (pcase id
              ("A" (insert "     (izolovaná, přístup jen z B)\n"))
              ("E" (insert "     ---\n"))
              ("H" (insert "     (průlezy G<->H)\n     ---\n"))))))
      (goto-char (point-min))
      (alien-rpg-view-mode))
    (switch-to-buffer "*Alien RPG*")))

(defun alien-rpg-key-locations ()
  "Klíčová místa."
  (interactive)
  (with-current-buffer (get-buffer-create "*Alien RPG*")
    (let ((inhibit-read-only t))
      (erase-buffer)
      (insert "\
Zbrane:      F-zbrojnice [F] Sever-střed
Lekar:       C-osetrovna [C] SZ
Pocitac:     B-mu-th-ur [B] Jih-střed
Komunikace:  GH-komunikacni-vez [GH]
Hangary:     G-hangar-01 [G] Z, G-hangar-02 [G] V
Kapsle:      I-zachranne-moduly [I]
Kryopody:    G-kryopody-z, G-kryopody-v [G]
Reaktor:     J-centralni-sachta [J]
Dílny:       H-dilny-z, H-dilny-v [H]
EVA:         G-eva-sz, G-eva-sv, G-eva-jz, G-eva-jv [G]
Šachta:      B<->C<->D<->E<->F<->G<->H<->I<->J
Pruchod B->A: B-pruchod-A [B] Západ
Průlezy F<->G: F1<->G1, F2<->G2, F5<->G5, F6<->G6, F7<->G7, F8<->G8
Průlezy G<->H: G3<->H3, G4<->H4, G7<->H7, G8<->H8, G9<->H9
"))
    (goto-char (point-min))
    (alien-rpg-view-mode))
  (switch-to-buffer "*Alien RPG*"))

(defun alien-rpg-status ()
  "Herní karta — kompletní stav postavy."
  (interactive)
  (let* ((ch alien-rpg-character)
         (st alien-rpg-state)
         (room (alien-rpg--current-room))
         (attrs (plist-get ch :attributes))
         (skills (plist-get ch :skills))
         (health (plist-get st :health))
         (stress (plist-get st :stress))
         (resolve (or (plist-get st :resolve) 4))
         (weapons (plist-get st :weapons))
         (armor (plist-get st :armor))
         (gear (plist-get ch :gear))
         (extra (plist-get st :extra-gear))
         (injuries (plist-get st :injuries))
         (conditions (plist-get st :conditions)))
    (with-current-buffer (get-buffer-create "*Alien RPG*")
      (let ((inhibit-read-only t))
        (erase-buffer)
        (insert (format "%s — %s, %s let\n\n"
                        (plist-get ch :name) (plist-get ch :career) (plist-get ch :age)))
        ;; Atributy a dovednosti - strukturovane
        (insert (format "STRENGTH %d:  Close Combat %d, Heavy Machinery %d, Stamina %d\n"
                        (plist-get attrs :strength)
                        (plist-get skills :close-combat) (plist-get skills :heavy-machinery)
                        (plist-get skills :stamina)))
        (insert (format "AGILITY  %d:  Mobility %d, Piloting %d, Ranged Combat %d\n"
                        (plist-get attrs :agility)
                        (plist-get skills :mobility) (plist-get skills :piloting)
                        (plist-get skills :ranged-combat)))
        (insert (format "WITS     %d:  Comtech %d, Observation %d, Survival %d\n"
                        (plist-get attrs :wits)
                        (plist-get skills :comtech) (plist-get skills :observation)
                        (plist-get skills :survival)))
        (insert (format "EMPATHY  %d:  Command %d, Manipulation %d, Medical Aid %d\n\n"
                        (plist-get attrs :empathy)
                        (plist-get skills :command) (plist-get skills :manipulation)
                        (plist-get skills :medical-aid)))
        ;; Stav
        (insert (format "Health: %d | Stress: %d | Resolve: %d | Story points: %s\n"
                        health stress resolve (or (plist-get st :story-points) 0)))
        ;; Talent
        (insert (format "Talent: %s\n" (plist-get ch :talent)))
        ;; Pozice
        (insert (format "Pozice: %s [%s]\n\n" (plist-get room :name) (plist-get room :id)))
        ;; Vybava
        (let ((all-gear (append gear extra)))
          (insert (format "Výbava: %s\n" (if all-gear (string-join all-gear ", ") "--"))))
        ;; Zbrane
        (if weapons
            (progn
              (insert "Zbraně:\n")
              (dolist (w weapons)
                (insert (format "  %s, mod %+d, DMG %d, %s, munice %d, váha %d\n"
                                (plist-get w :name)
                                (or (plist-get w :modifier) 0)
                                (or (plist-get w :damage) 0)
                                (or (plist-get w :range) "?")
                                (or (plist-get w :ammo) 0)
                                (or (plist-get w :weight) 0)))))
          (insert "Zbraně: --\n"))
        ;; Brneni
        (insert (format "Brnění: %s\n"
                        (if armor
                            (format "%s (L%d/W%d)"
                                    (or (plist-get armor :name) "?")
                                    (or (plist-get armor :level) 0)
                                    (or (plist-get armor :weight) 0))
                          "--")))
        ;; Zraneni a stavy
        (insert (format "Zranění: %s\n" (if injuries (string-join injuries ", ") "--")))
        (insert (format "Stavy: %s"
                        (mapconcat (lambda (c)
                                     (format "[%s] %s"
                                             (if (member c conditions) "X" " ") c))
                                   alien-rpg-known-conditions ", ")))
        (let ((extra-conds (cl-remove-if (lambda (c) (member c alien-rpg-known-conditions)) conditions)))
          (when extra-conds
            (insert (format ", %s" (mapconcat (lambda (c) (format "[X] %s" c)) extra-conds ", ")))))
        (insert "\n")
        ;; Signature
        (insert (format "Signature: %s\n" (or (plist-get ch :signature-item) "--"))))
      (goto-char (point-min))
      (alien-rpg-view-mode))
    (switch-to-buffer "*Alien RPG*")))

(defun alien-rpg-skills ()
  "Dovednosti — seřazené od nejsilnějších."
  (interactive)
  (let* ((skill-data
          (mapcar (lambda (sk)
                    (let* ((key (car sk))
                           (attr-key (cdr sk))
                           (name (cdr (assq key alien-rpg-skill-names)))
                           (attr-abbr (cdr (assq attr-key alien-rpg-attr-abbrevs)))
                           (attr-val (plist-get (plist-get alien-rpg-character :attributes) attr-key))
                           (skill-val (plist-get (plist-get alien-rpg-character :skills) key))
                           (total (+ attr-val skill-val)))
                      (list total name attr-abbr attr-val skill-val)))
                  alien-rpg-skill-attributes))
         (sorted (sort skill-data (lambda (a b) (> (car a) (car b))))))
    (with-current-buffer (get-buffer-create "*Alien RPG*")
      (let ((inhibit-read-only t))
        (erase-buffer)
        (dolist (s sorted)
          (let ((total (nth 0 s))
                (name (nth 1 s))
                (abbr (nth 2 s))
                (attr (nth 3 s))
                (sk (nth 4 s)))
            (if (> sk 0)
                (insert (format "%d  %-18s (%s %d + %d)\n" total name abbr attr sk))
              (insert (format "%d  %-18s (%s %d)\n" total name abbr attr)))))
        (insert (format "\nTalent: %s\n" (plist-get alien-rpg-character :talent))))
      (goto-char (point-min))
      (alien-rpg-view-mode))
    (switch-to-buffer "*Alien RPG*")))

;; --- Upravy stavu ---

(defun alien-rpg-set-health (n)
  "Změň Health (+1/-1 nebo absolutně 0-4)."
  (interactive "nHealth (+/-N nebo 0-4): ")
  (let* ((current (plist-get alien-rpg-state :health))
         (new-val (if (and (>= n -4) (<= n 4) (/= n current)
                           (or (< n 0) (> (abs (- n current)) 1)))
                      (max 0 (min 4 (+ current n)))
                    (max 0 (min 4 n)))))
    (setq alien-rpg-state (plist-put alien-rpg-state :health new-val))
    (alien-rpg--autosave)
    (message "Health: %d/4 (%s%d)" new-val (if (>= (- new-val current) 0) "+" "") (- new-val current))))

(defun alien-rpg-set-stress (n)
  "Změň Stress (+N/-N relativně, zadej číslo)."
  (interactive "nStress (+/-N): ")
  (let* ((current (plist-get alien-rpg-state :stress))
         (new-val (max 0 (+ current n))))
    (setq alien-rpg-state (plist-put alien-rpg-state :stress new-val))
    (alien-rpg--autosave)
    (message "Stress: %d (%s%d)" new-val (if (>= n 0) "+" "") n)))

(defun alien-rpg-set-resolve (n)
  "Změň Resolve (+/-N)."
  (interactive "nResolve (+/-N): ")
  (let* ((current (or (plist-get alien-rpg-state :resolve) 4))
         (new-val (max 0 (+ current n))))
    (setq alien-rpg-state (plist-put alien-rpg-state :resolve new-val))
    (alien-rpg--autosave)
    (message "Resolve: %d (%s%d)" new-val (if (>= n 0) "+" "") n)))

(defun alien-rpg-set-stat ()
  "Univerzální editor — změň cokoliv na kartě."
  (interactive)
  (let* ((st-choices '(("Health" . :health)
                       ("Stress" . :stress)
                       ("Resolve" . :resolve)
                       ("Story points" . :story-points)))
         (attr-choices '(("Strength" . (:attributes :strength))
                         ("Agility" . (:attributes :agility))
                         ("Wits" . (:attributes :wits))
                         ("Empathy" . (:attributes :empathy))))
         (skill-choices '(("Close Combat" . (:skills :close-combat))
                          ("Heavy Machinery" . (:skills :heavy-machinery))
                          ("Stamina" . (:skills :stamina))
                          ("Mobility" . (:skills :mobility))
                          ("Piloting" . (:skills :piloting))
                          ("Ranged Combat" . (:skills :ranged-combat))
                          ("Comtech" . (:skills :comtech))
                          ("Observation" . (:skills :observation))
                          ("Survival" . (:skills :survival))
                          ("Command" . (:skills :command))
                          ("Manipulation" . (:skills :manipulation))
                          ("Medical Aid" . (:skills :medical-aid))))
         (all-names (sort (append (mapcar #'car st-choices) (mapcar #'car attr-choices) (mapcar #'car skill-choices))
                         #'string<))
         (choice (completing-read "Editovat: " all-names nil t))
         (st-match (assoc choice st-choices))
         (attr-match (assoc choice attr-choices))
         (skill-match (assoc choice skill-choices)))
    (cond
     ;; State value (health, stress, resolve, story-points)
     (st-match
      (let* ((key (cdr st-match))
             (current (or (plist-get alien-rpg-state key) 0))
             (new-val (read-number (format "%s [%d] -> " choice current) current)))
        (setq alien-rpg-state (plist-put alien-rpg-state key (max 0 new-val)))
        (alien-rpg--autosave)
        (message "%s: %d -> %d" choice current new-val)))
     ;; Attribute
     (attr-match
      (let* ((path (cdr attr-match))
             (current (plist-get (plist-get alien-rpg-character (car path)) (cadr path)))
             (new-val (read-number (format "%s [%d] -> " choice current) current)))
        (plist-put (plist-get alien-rpg-character (car path)) (cadr path) new-val)
        (message "%s: %d -> %d" choice current new-val)))
     ;; Skill
     (skill-match
      (let* ((path (cdr skill-match))
             (current (plist-get (plist-get alien-rpg-character (car path)) (cadr path)))
             (new-val (read-number (format "%s [%d] -> " choice current) current)))
        (plist-put (plist-get alien-rpg-character (car path)) (cadr path) new-val)
        (message "%s: %d -> %d" choice current new-val))))))

(defun alien-rpg-dice ()
  "Kolik kostek hodit — vyber dovednost."
  (interactive)
  (let* ((stress (plist-get alien-rpg-state :stress))
         (choices (alien-rpg--sort-candidates
                   (mapcar (lambda (sk)
                             (let* ((key (car sk))
                                    (attr-key (cdr sk))
                                    (name (cdr (assq key alien-rpg-skill-names)))
                                    (attr-val (plist-get (plist-get alien-rpg-character :attributes) attr-key))
                                    (skill-val (plist-get (plist-get alien-rpg-character :skills) key))
                                    (base (+ attr-val skill-val))
                                    (attr-abbr (cdr (assq attr-key alien-rpg-attr-abbrevs))))
                               (cons (format "%-18s %d cerne + %d zlute = %d celkem"
                                             name base stress (+ base stress))
                                     (list name base attr-abbr attr-val skill-val))))
                           alien-rpg-skill-attributes)))
         (choice (completing-read "Hod na: " choices nil t))
         (data (cdr (assoc choice choices)))
         (name (nth 0 data))
         (base (nth 1 data)))
    (with-current-buffer (get-buffer-create "*Alien RPG*")
      (let ((inhibit-read-only t))
        (erase-buffer)
        (insert (format "%s\n" name))
        (insert (format "%d cernych kostek (zaklad)\n" base))
        (insert (format "%d zlutych kostek (stress)\n" stress))
        (insert (format "%d kostek celkem\n" (+ base stress))))
      (goto-char (point-min))
      (alien-rpg-view-mode))
    (switch-to-buffer "*Alien RPG*")))

(defun alien-rpg-add-injury (injury)
  "Přidej zranění."
  (interactive "sZranění: ")
  (setq alien-rpg-state (plist-put alien-rpg-state :injuries
             (append (plist-get alien-rpg-state :injuries) (list injury))))
  (alien-rpg--autosave)
  (message "Zranění: %s" injury))

(defun alien-rpg-add-gear (item)
  "Přidej výbavu."
  (interactive "sVýbava: ")
  (setq alien-rpg-state (plist-put alien-rpg-state :extra-gear
             (append (plist-get alien-rpg-state :extra-gear) (list item))))
  (alien-rpg--autosave)
  (message "Výbava: %s" item))

(defun alien-rpg--add-weapon-interactive ()
  "Interaktivně přidej novou zbraň."
  (let* ((name (read-string "Název zbraně: "))
         (modifier (read-number "Modifier: " 0))
         (damage (read-number "Damage: " 1))
         (range (completing-read "Range: " '("Engaged" "Short" "Medium" "Long" "Extreme") nil t))
         (ammo (read-number "Ammo (0=neomezeno): " 0))
         (weight (read-number "Weight: " 1))
         (weapon (list :name name :modifier modifier :damage damage
                       :range range :ammo ammo :weight weight)))
    (setq alien-rpg-state (plist-put alien-rpg-state :weapons
               (append (plist-get alien-rpg-state :weapons) (list weapon))))
    (alien-rpg--autosave)
    (message "Zbraň: %s mod%+d/DMG%d/%s" name modifier damage range)))

(defun alien-rpg-add-weapon ()
  "Přidej zbraň se všemi parametry."
  (interactive)
  (alien-rpg--add-weapon-interactive))

(defun alien-rpg-add-armor ()
  "Nastav brnění."
  (interactive)
  (let* ((name (read-string "Brnění: "))
         (level (read-number "Level: " 1))
         (weight (read-number "Weight: " 1))
         (armor (list :name name :level level :weight weight)))
    (setq alien-rpg-state (plist-put alien-rpg-state :armor armor))
    (alien-rpg--autosave)
    (message "Brnění: %s (L%d/W%d)" name level weight)))

(defun alien-rpg-add-condition ()
  "Přidej stav (Fatigued, Radiation, ...)."
  (interactive)
  (let ((cond-name (read-string "Stav: ")))
    (setq alien-rpg-state (plist-put alien-rpg-state :conditions
               (append (plist-get alien-rpg-state :conditions) (list cond-name))))
    (alien-rpg--autosave)
    (message "Stav: %s" cond-name)))


(defun alien-rpg-add-note (note)
  "Přidej poznámku."
  (interactive "sPoznamka: ")
  (setq alien-rpg-state (plist-put alien-rpg-state :notes
             (append (plist-get alien-rpg-state :notes)
                     (list (format "[%s] %s" (format-time-string "%H:%M") note)))))
  (alien-rpg--autosave)
  (message "Poznámka uložena."))

(defun alien-rpg-show-notes ()
  "Zobraz poznámky."
  (interactive)
  (with-current-buffer (get-buffer-create "*Alien RPG*")
    (let ((inhibit-read-only t)
          (notes (plist-get alien-rpg-state :notes)))
      (erase-buffer)
      (if notes
          (dolist (n notes) (insert (format "%s\n" n)))
        (insert "(žádné poznámky)\n")))
    (goto-char (point-min))
    (alien-rpg-view-mode))
  (switch-to-buffer "*Alien RPG*"))

;; ====================================================================
;; POZNAMKY K MISTNOSTEM
;; ====================================================================

(defun alien-rpg-add-room-note (note)
  "Přidej poznámku k aktuální místnosti."
  (interactive "sPoznámka k místnosti: ")
  (let* ((room-id (plist-get alien-rpg-state :current-room))
         (room (alien-rpg--get-room room-id))
         (room-notes (plist-get alien-rpg-state :room-notes))
         (entry (assoc room-id room-notes))
         (timestamped (format "[%s] %s" (format-time-string "%H:%M") note)))
    (if entry
        (setcdr entry (append (cdr entry) (list timestamped)))
      (setq alien-rpg-state
            (plist-put alien-rpg-state :room-notes
                       (append room-notes (list (list room-id timestamped))))))
    (alien-rpg--autosave)
    (message "%s: %s" (plist-get room :name) note)))

(defun alien-rpg-show-room-notes ()
  "Zobraz všechny poznámky k místnostem."
  (interactive)
  (let ((room-notes (plist-get alien-rpg-state :room-notes))
        (global-notes (plist-get alien-rpg-state :notes)))
    (with-current-buffer (get-buffer-create "*Alien RPG*")
      (let ((inhibit-read-only t))
        (erase-buffer)
        (if room-notes
            (dolist (entry room-notes)
              (let* ((rid (car entry))
                     (notes (cdr entry))
                     (room (alien-rpg--get-room rid)))
                (insert (format "%s [%s]:\n"
                                (if room (plist-get room :name) rid) rid))
                (dolist (n notes)
                  (insert (format "  %s\n" n)))
                (insert "\n")))
          (insert "(žádné poznámky k místnostem)\n"))
        (when global-notes
          (insert "Globální poznámky:\n")
          (dolist (n global-notes)
            (insert (format "  %s\n" n)))))
      (goto-char (point-min))
      (alien-rpg-view-mode))
    (switch-to-buffer "*Alien RPG*")))

;; ====================================================================
;; SPRAVA INVENTARE
;; ====================================================================

(defun alien-rpg--numbered-candidates (items &optional format-fn)
  "Očísluj ITEMS pro completing-read. Vrací alist (label . index).
FORMAT-FN dostane item, vrátí string. Bez FORMAT-FN se item použije přímo."
  (let ((i 0))
    (mapcar (lambda (item)
              (prog1
                  (cons (format "%d. %s" (1+ i)
                                (if format-fn (funcall format-fn item) item))
                        i)
                (setq i (1+ i))))
            items)))

(defun alien-rpg--remove-nth (n lst)
  "Odstraň N-tý prvek z LST (0-based)."
  (append (cl-subseq lst 0 n)
          (when (< (1+ n) (length lst))
            (cl-subseq lst (1+ n)))))

(defun alien-rpg-gear ()
  "Výbava — přidat nebo odebrat."
  (interactive)
  (let* ((extra (plist-get alien-rpg-state :extra-gear))
         (actions (if extra '("Přidat" "Odebrat") '("Přidat")))
         (action (if extra
                     (completing-read "Výbava: " actions nil t)
                   "Přidat")))
    (cond
     ((string= action "Přidat")
      (let ((item (read-string "Nová výbava: ")))
        (setq alien-rpg-state (plist-put alien-rpg-state :extra-gear
                   (append extra (list item))))
        (alien-rpg--autosave)
        (message "Výbava: %s" item)))
     ((string= action "Odebrat")
      (let* ((candidates (alien-rpg--numbered-candidates extra))
             (choice (completing-read "Odebrat: " candidates nil t))
             (idx (cdr (assoc choice candidates))))
        (setq alien-rpg-state (plist-put alien-rpg-state :extra-gear
                   (alien-rpg--remove-nth idx extra)))
        (alien-rpg--autosave)
        (message "Odebráno: %s" (nth idx extra)))))))

(defun alien-rpg--weapon-label (w)
  "Formátuj zbraň W pro zobrazení."
  (format "%s mod%+d/DMG%d/%s/%dks/W%d"
          (plist-get w :name)
          (or (plist-get w :modifier) 0)
          (or (plist-get w :damage) 0)
          (or (plist-get w :range) "?")
          (or (plist-get w :ammo) 0)
          (or (plist-get w :weight) 0)))

(defun alien-rpg-weapon ()
  "Zbraně — přidat, odebrat, upravit munici."
  (interactive)
  (let* ((weapons (plist-get alien-rpg-state :weapons))
         (actions (if weapons '("Přidat" "Munice" "Upravit" "Odebrat") '("Přidat")))
         (action (if weapons
                     (completing-read "Zbraně: " actions nil t)
                   "Přidat")))
    (cond
     ((string= action "Přidat")
      (alien-rpg--add-weapon-interactive))
     (t
      (let* ((candidates (alien-rpg--numbered-candidates
                          weapons #'alien-rpg--weapon-label))
             (choice (completing-read "Která zbraň: " candidates nil t))
             (idx (cdr (assoc choice candidates)))
             (weapon (nth idx weapons)))
        (cond
         ((string= action "Munice")
          (let* ((current (or (plist-get weapon :ammo) 0))
                 (delta (read-number (format "Munice [%d] +/-: " current) -1))
                 (new-ammo (max 0 (+ current delta))))
            (plist-put weapon :ammo new-ammo)
            (alien-rpg--autosave)
            (message "%s munice: %d (%s%d)"
                     (plist-get weapon :name) new-ammo
                     (if (>= delta 0) "+" "") delta)))
         ((string= action "Odebrat")
          (setq alien-rpg-state
                (plist-put alien-rpg-state :weapons
                           (alien-rpg--remove-nth idx weapons)))
          (alien-rpg--autosave)
          (message "Odebráno: %s" (plist-get weapon :name)))
         ((string= action "Upravit")
          (let* ((name (read-string "Název: " (plist-get weapon :name)))
                 (modifier (read-number "Modifier: " (or (plist-get weapon :modifier) 0)))
                 (damage (read-number "Damage: " (or (plist-get weapon :damage) 1)))
                 (range (completing-read "Range: "
                                         '("Engaged" "Short" "Medium" "Long" "Extreme") nil t
                                         nil nil (or (plist-get weapon :range) "Short")))
                 (ammo (read-number "Ammo: " (or (plist-get weapon :ammo) 0)))
                 (weight (read-number "Weight: " (or (plist-get weapon :weight) 1))))
            (plist-put weapon :name name)
            (plist-put weapon :modifier modifier)
            (plist-put weapon :damage damage)
            (plist-put weapon :range range)
            (plist-put weapon :ammo ammo)
            (plist-put weapon :weight weight)
            (alien-rpg--autosave)
            (message "Upraveno: %s mod%+d/DMG%d/%s" name modifier damage range)))))))))

(defun alien-rpg-armor ()
  "Brnění — nasadit nebo odebrat."
  (interactive)
  (let* ((armor (plist-get alien-rpg-state :armor))
         (action (if armor
                     (completing-read "Brnění: " '("Nasadit nové" "Odebrat") nil t)
                   "Nasadit nové")))
    (cond
     ((string= action "Nasadit nové")
      (let* ((name (read-string "Brnění: "))
             (level (read-number "Level: " 1))
             (weight (read-number "Weight: " 1))
             (new-armor (list :name name :level level :weight weight)))
        (setq alien-rpg-state (plist-put alien-rpg-state :armor new-armor))
        (alien-rpg--autosave)
        (message "Brnění: %s (L%d/W%d)" name level weight)))
     ((string= action "Odebrat")
      (setq alien-rpg-state (plist-put alien-rpg-state :armor nil))
      (alien-rpg--autosave)
      (message "Brnění odebráno.")))))

(defun alien-rpg-injury ()
  "Zranění — přidat nebo vyléčit."
  (interactive)
  (let* ((injuries (plist-get alien-rpg-state :injuries))
         (actions (if injuries '("Přidat" "Vyléčit") '("Přidat")))
         (action (if injuries
                     (completing-read "Zranění: " actions nil t)
                   "Přidat")))
    (cond
     ((string= action "Přidat")
      (let ((injury (read-string "Zranění: ")))
        (setq alien-rpg-state (plist-put alien-rpg-state :injuries
                   (append injuries (list injury))))
        (alien-rpg--autosave)
        (message "Zranění: %s" injury)))
     ((string= action "Vyléčit")
      (let* ((candidates (alien-rpg--numbered-candidates injuries))
             (choice (completing-read "Vyléčit: " candidates nil t))
             (idx (cdr (assoc choice candidates))))
        (setq alien-rpg-state (plist-put alien-rpg-state :injuries
                   (alien-rpg--remove-nth idx injuries)))
        (alien-rpg--autosave)
        (message "Vyléčeno: %s" (nth idx injuries)))))))

(defvar alien-rpg-known-conditions
  '("Fatigued" "Radiation")
  "Stavy z herní karty.")

(defvar alien-rpg-panic-effects
  '("Jumpy" "Freeze" "Tunnel Vision" "Seek Cover"
    "Aggravated" "Scream" "Shakes" "Flee"
    "Frantic" "Frenzy" "Deflated" "Catatonic"
    "Paranoid" "Hesitant")
  "Panické reakce (panic tabulka).")

(defun alien-rpg-condition ()
  "Přepni stav/podmínku — zaškrtni nebo odškrtni."
  (interactive)
  (let* ((conditions (plist-get alien-rpg-state :conditions))
         (action (completing-read "Podmínky: "
                                  '("Přepnout stav" "Panická reakce" "Vlastní") nil t)))
    (cond
     ((string= action "Přepnout stav")
      (let* ((candidates
              (mapcar (lambda (c)
                        (format "[%s] %s"
                                (if (member c conditions) "X" " ") c))
                      alien-rpg-known-conditions))
             (choice (completing-read "Stav: " candidates nil t))
             (cond-name (substring choice 4)))
        (if (member cond-name conditions)
            (progn
              (setq alien-rpg-state
                    (plist-put alien-rpg-state :conditions
                               (remove cond-name conditions)))
              (alien-rpg--autosave)
              (message "[ ] %s" cond-name))
          (setq alien-rpg-state
                (plist-put alien-rpg-state :conditions
                           (append conditions (list cond-name))))
          (alien-rpg--autosave)
          (message "[X] %s" cond-name))))
     ((string= action "Panická reakce")
      (let* ((candidates
              (mapcar (lambda (name)
                        (format "[%s] %s"
                                (if (member name conditions) "X" " ")
                                name))
                      alien-rpg-panic-effects))
             (choice (completing-read "Panika: " candidates nil t))
             (cond-name (substring choice 4)))
        (if (member cond-name conditions)
            (progn
              (setq alien-rpg-state
                    (plist-put alien-rpg-state :conditions
                               (remove cond-name conditions)))
              (alien-rpg--autosave)
              (message "[ ] %s" cond-name))
          (setq alien-rpg-state
                (plist-put alien-rpg-state :conditions
                           (append conditions (list cond-name))))
          (alien-rpg--autosave)
          (message "[X] %s" cond-name))))
     ((string= action "Vlastní")
      (let ((cond-name (read-string "Název: ")))
        (if (member cond-name conditions)
            (progn
              (setq alien-rpg-state
                    (plist-put alien-rpg-state :conditions
                               (remove cond-name conditions)))
              (alien-rpg--autosave)
              (message "[ ] %s" cond-name))
          (setq alien-rpg-state
                (plist-put alien-rpg-state :conditions
                           (append conditions (list cond-name))))
          (alien-rpg--autosave)
          (message "[X] %s" cond-name)))))))

;; ====================================================================
;; DISPATCH, HELP, VIEW MODE
;; ====================================================================

(defvar alien-rpg--dispatch-commands
  '(("Brnění"                 . alien-rpg-armor)
    ("Dovednosti"             . alien-rpg-skills)
    ("Editovat stat"          . alien-rpg-set-stat)
    ("Health +/-"             . alien-rpg-set-health)
    ("Kde jsem"               . alien-rpg-where-am-i)
    ("Klíčová místa"          . alien-rpg-key-locations)
    ("Kostky"                 . alien-rpg-dice)
    ("Načíst stav"            . alien-rpg-load-state)
    ("Nápověda"               . alien-rpg-help)
    ("Najít cestu"            . alien-rpg-find-path)
    ("Najít místnost"         . alien-rpg-find-room)
    ("Paluba přehled"         . alien-rpg-deck-overview)
    ("Podmínka"               . alien-rpg-condition)
    ("Poznámka globální"      . alien-rpg-add-note)
    ("Poznámka k místnosti"   . alien-rpg-add-room-note)
    ("Poznámky"               . alien-rpg-show-room-notes)
    ("Přehled stanice"        . alien-rpg-station-overview)
    ("Přesun"                 . alien-rpg-move)
    ("Resolve +/-"            . alien-rpg-set-resolve)
    ("Stav postavy"           . alien-rpg-status)
    ("Stress +/-"             . alien-rpg-set-stress)
    ("Teleport"               . alien-rpg-teleport)
    ("Uložit stav"            . alien-rpg-save-state)
    ("Výbava"                 . alien-rpg-gear)
    ("Zbraně"                 . alien-rpg-weapon)
    ("Zranění"                . alien-rpg-injury))
  "Všechny příkazy pro dispatch.")

(defun alien-rpg-dispatch ()
  "Vyber příkaz ze seznamu."
  (interactive)
  (let* ((names (mapcar #'car alien-rpg--dispatch-commands))
         (choice (completing-read "Příkaz: " names nil t))
         (fn (cdr (assoc choice alien-rpg--dispatch-commands))))
    (call-interactively fn)))

(defun alien-rpg-help ()
  "Zobraz nápovědu — klávesové zkratky."
  (interactive)
  (with-current-buffer (get-buffer-create "*Alien RPG*")
    (let ((inhibit-read-only t))
      (erase-buffer)
      (insert "Alien RPG — klávesové zkratky\n\n")
      (insert "SPC G SPC  Dispatch (všechny příkazy)\n")
      (insert "SPC G ?    Tato nápověda\n\n")
      (insert "--- Navigace ---\n")
      (insert "SPC G w    Kde jsem\n")
      (insert "SPC G m    Přesun (sousední místnost)\n")
      (insert "SPC G t    Teleport (kamkoliv)\n")
      (insert "SPC G f    Najít místnost (info)\n")
      (insert "SPC G p    Najít cestu\n")
      (insert "SPC G d    Přehled paluby\n")
      (insert "SPC G o    Přehled stanice\n")
      (insert "SPC G k    Klíčová místa\n\n")
      (insert "--- Postava ---\n")
      (insert "SPC G s    Stav postavy (herní karta)\n")
      (insert "SPC G i    Dovednosti (seřazené)\n")
      (insert "SPC G h    Health +/-\n")
      (insert "SPC G S    Stress +/-\n")
      (insert "SPC G r    Kostky (dice calc)\n")
      (insert "SPC G e    Editovat stat/skill\n\n")
      (insert "--- Inventář (přidat/odebrat/upravit) ---\n")
      (insert "SPC G g    Výbava\n")
      (insert "SPC G W    Zbraně\n")
      (insert "SPC G a    Brnění\n")
      (insert "SPC G j    Zranění\n")
      (insert "SPC G c    Podmínky\n\n")
      (insert "--- Poznámky ---\n")
      (insert "SPC G n    Poznámka k místnosti\n")
      (insert "SPC G N    Zobrazit poznámky\n")
      (insert "SPC G x    Globální poznámka\n\n")
      (insert "--- Uložení ---\n")
      (insert "SPC G q    Uložit\n")
      (insert "SPC G Q    Načíst\n\n")
      (insert "--- V bufferu *Alien RPG* ---\n")
      (insert "m  přesun | w  kde jsem | t  teleport | s  stav\n")
      (insert "d  paluba | r  kostky   | f  místnost | p  cesta\n")
      (insert "n  poznámka k místnosti | N  poznámky | SPC dispatch\n")
      (insert "?  tato nápověda        | q  zavřít\n"))
    (goto-char (point-min))
    (alien-rpg-view-mode))
  (switch-to-buffer "*Alien RPG*"))

(defvar alien-rpg-view-mode-map
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map special-mode-map)
    (define-key map "m" #'alien-rpg-move)
    (define-key map "w" #'alien-rpg-where-am-i)
    (define-key map "t" #'alien-rpg-teleport)
    (define-key map "s" #'alien-rpg-status)
    (define-key map "d" #'alien-rpg-deck-overview)
    (define-key map "r" #'alien-rpg-dice)
    (define-key map "p" #'alien-rpg-find-path)
    (define-key map "f" #'alien-rpg-find-room)
    (define-key map "n" #'alien-rpg-add-room-note)
    (define-key map "N" #'alien-rpg-show-room-notes)
    (define-key map " " #'alien-rpg-dispatch)
    (define-key map "?" #'alien-rpg-help)
    map)
  "Keymap pro *Alien RPG* buffer.")

(define-derived-mode alien-rpg-view-mode special-mode "Alien-RPG"
  "Režim pro *Alien RPG* buffer. Klávesy: m w t s d r p f n N SPC ?")

;; ====================================================================
;; DOOM EMACS KEYBINDINGS
;; ====================================================================

(with-eval-after-load 'doom-keybinds
  (map! :leader
        (:prefix ("G" . "Alien RPG")
         :desc "Dispatch"       "SPC" #'alien-rpg-dispatch
         :desc "Nápověda"       "?" #'alien-rpg-help
         :desc "Kde jsem"       "w" #'alien-rpg-where-am-i
         :desc "Přesun"         "m" #'alien-rpg-move
         :desc "Teleport"       "t" #'alien-rpg-teleport
         :desc "Najít místnost" "f" #'alien-rpg-find-room
         :desc "Najít cestu"    "p" #'alien-rpg-find-path
         :desc "Přehled paluby" "d" #'alien-rpg-deck-overview
         :desc "Přehled stanice" "o" #'alien-rpg-station-overview
         :desc "Klíčová místa"  "k" #'alien-rpg-key-locations
         :desc "Stav postavy"   "s" #'alien-rpg-status
         :desc "Dovednosti"     "i" #'alien-rpg-skills
         :desc "Health"         "h" #'alien-rpg-set-health
         :desc "Stress"         "S" #'alien-rpg-set-stress
         :desc "Kostky"         "r" #'alien-rpg-dice
         :desc "Editovat"       "e" #'alien-rpg-set-stat
         :desc "Zranění"        "j" #'alien-rpg-injury
         :desc "Výbava"         "g" #'alien-rpg-gear
         :desc "Zbraně"         "W" #'alien-rpg-weapon
         :desc "Brnění"         "a" #'alien-rpg-armor
         :desc "Podmínky"       "c" #'alien-rpg-condition
         :desc "Pozn. místnost" "n" #'alien-rpg-add-room-note
         :desc "Poznámky"       "N" #'alien-rpg-show-room-notes
         :desc "Glob. pozn."    "x" #'alien-rpg-add-note
         :desc "Uložit"         "q" #'alien-rpg-save-state
         :desc "Načíst"         "Q" #'alien-rpg-load-state)))

(provide 'alien-rpg)
;;; alien-rpg.el ends here
