;;; 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