Room notes, sorted completions, inventory mgmt, view mode, dispatch
1. Room-specific notes: SPC G n adds timestamped note to current room, displayed in where-am-i and find-room output. SPC G N shows all. 2. Alphabetical sorting in all completing-read candidate lists. 3. Inventory management: SPC G v prefix — remove/modify gear, weapons (including ammo tracking), injuries, conditions, armor, tiny items. 4. UX: alien-rpg-view-mode with local keys (m/w/t/s/d/r/p/f/n/N/SPC/?), dispatch command (SPC G SPC) lists all commands, help (SPC G ?). Refactored room info display into shared alien-rpg--insert-room-info. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
25
CLAUDE.md
25
CLAUDE.md
@@ -8,7 +8,7 @@ Accessible tabletop RPG gaming engine for the Alien RPG space station USCSS CETO
|
||||
|
||||
## Architecture
|
||||
|
||||
**alien-rpg.el** (main engine, ~1370 lines, lexical-binding):
|
||||
**alien-rpg.el** (main engine, ~1660 lines, lexical-binding):
|
||||
|
||||
- **Data**: `alien-rpg-rooms` (112 rooms as connection graph), `alien-rpg-decks` (10 decks A-J), `alien-rpg-character` (mutable during session), `alien-rpg-state` (mutable, auto-saved). Station name in `alien-rpg-station-name`.
|
||||
- **Room IDs**: ASCII slugs (e.g., `B-ridici-stredisko`). Display names use Czech diacritics (`Řídící středisko`).
|
||||
@@ -18,7 +18,12 @@ Accessible tabletop RPG gaming engine for the Alien RPG space station USCSS CETO
|
||||
- **No průlez rooms**: Průlezy (hatches between decks) are NOT separate rooms. They are direct connections between the rooms they physically sit in. Cross-deck connections noted in room `:desc`.
|
||||
- **Dice calculator**: `SPC G r` — black base dice (attribute + skill) + yellow stress dice. Player rolls physical dice.
|
||||
- **Weapons/Armor**: Structured plists — weapons: `(:name :modifier :damage :range :ammo :weight)`, armor: `(:name :level :weight)`.
|
||||
- **State**: Health, stress, resolve, story-points, injuries, conditions, weapons, armor, gear, tiny-items, notes. Auto-saves via `alien-rpg--autosave`. No buddy/rival/xp (not used in this campaign).
|
||||
- **State**: Health, stress, resolve, story-points, injuries, conditions, weapons, armor, gear, tiny-items, notes, room-notes. Auto-saves via `alien-rpg--autosave`. No buddy/rival/xp (not used in this campaign).
|
||||
- **Room notes**: Per-room notes stored as alist `((room-id note1 note2 ...) ...)` in `:room-notes`. Timestamped. Displayed in `where-am-i` and `find-room` output.
|
||||
- **Sorting**: All `completing-read` candidate lists sorted alphabetically via `alien-rpg--sort-candidates`.
|
||||
- **View mode**: `alien-rpg-view-mode` (derived from `special-mode`) applied to `*Alien RPG*` buffer with local keybindings.
|
||||
- **Dispatch**: `alien-rpg-dispatch` lists all commands in completing-read for discoverability.
|
||||
- **Inventory management**: Commands to remove/modify gear, weapons (including ammo), injuries, conditions, armor, tiny items.
|
||||
- **Character**: prof. Héctor Navarre, biochemický inženýr, 74 let. Attributes and skills editable via `SPC G e`.
|
||||
- **Output**: All commands output to `*Alien RPG*` buffer via `switch-to-buffer` (not `pop-to-buffer` — avoids Doom popup behavior that confuses screen readers).
|
||||
|
||||
@@ -26,6 +31,8 @@ Accessible tabletop RPG gaming engine for the Alien RPG space station USCSS CETO
|
||||
|
||||
| Key | Command | Function |
|
||||
|-----|---------|----------|
|
||||
| `SPC` | Dispatch | `alien-rpg-dispatch` |
|
||||
| `?` | Nápověda | `alien-rpg-help` |
|
||||
| `w` | Kde jsem | `alien-rpg-where-am-i` |
|
||||
| `m` | Přesun | `alien-rpg-move` |
|
||||
| `t` | Teleport | `alien-rpg-teleport` |
|
||||
@@ -45,10 +52,20 @@ Accessible tabletop RPG gaming engine for the Alien RPG space station USCSS CETO
|
||||
| `W` | Zbraň | `alien-rpg-add-weapon` |
|
||||
| `a` | Brnění | `alien-rpg-add-armor` |
|
||||
| `c` | Stav/condition | `alien-rpg-add-condition` |
|
||||
| `n` | Poznámka | `alien-rpg-add-note` |
|
||||
| `N` | Poznámky | `alien-rpg-show-notes` |
|
||||
| `n` | Poznámka k místnosti | `alien-rpg-add-room-note` |
|
||||
| `N` | Poznámky | `alien-rpg-show-room-notes` |
|
||||
| `x` | Globální poznámka | `alien-rpg-add-note` |
|
||||
| `q` | Uložit | `alien-rpg-save-state` |
|
||||
| `Q` | Načíst | `alien-rpg-load-state` |
|
||||
| `v g` | Spravovat výbavu | `alien-rpg-manage-gear` |
|
||||
| `v w` | Spravovat zbraně | `alien-rpg-manage-weapon` |
|
||||
| `v a` | Spravovat brnění | `alien-rpg-manage-armor` |
|
||||
| `v j` | Spravovat zranění | `alien-rpg-manage-injury` |
|
||||
| `v c` | Spravovat podmínky | `alien-rpg-manage-condition` |
|
||||
| `v t` | Spravovat drobné věci | `alien-rpg-manage-tiny-items` |
|
||||
|
||||
**Local keybindings** (in `*Alien RPG*` buffer via `alien-rpg-view-mode`):
|
||||
`m` přesun, `w` kde jsem, `t` teleport, `s` stav, `d` paluba, `r` kostky, `f` místnost, `p` cesta, `n` poznámka k místnosti, `N` poznámky, `SPC` dispatch, `?` nápověda, `q` zavřít.
|
||||
|
||||
**Reference docs** (org-mode, Czech):
|
||||
- `paluby/paluba-{A..J}.org` + `paluba-GH.org` — deck descriptions
|
||||
|
||||
544
alien-rpg.el
544
alien-rpg.el
@@ -638,7 +638,8 @@
|
||||
:injuries ()
|
||||
:conditions ()
|
||||
:story-points 0
|
||||
:notes ())
|
||||
:notes ()
|
||||
:room-notes nil)
|
||||
"Dynamický herní stav.")
|
||||
|
||||
(defvar alien-rpg-state-file
|
||||
@@ -681,6 +682,25 @@
|
||||
(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))
|
||||
@@ -752,6 +772,8 @@
|
||||
(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 ()
|
||||
@@ -772,11 +794,9 @@
|
||||
;; INTERAKTIVNI PRIKAZY
|
||||
;; ====================================================================
|
||||
|
||||
(defun alien-rpg-where-am-i ()
|
||||
"Kde jsem — popis pro screen reader."
|
||||
(interactive)
|
||||
(let* ((room (alien-rpg--current-room))
|
||||
(deck (alien-rpg--get-deck (plist-get room :deck)))
|
||||
(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
|
||||
@@ -791,43 +811,54 @@
|
||||
(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)
|
||||
(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))))
|
||||
(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 ", "))))))
|
||||
(alien-rpg--insert-room-info room))
|
||||
(goto-char (point-min))
|
||||
(special-mode))
|
||||
(alien-rpg-view-mode))
|
||||
(switch-to-buffer "*Alien RPG*")))
|
||||
|
||||
(defun alien-rpg-move ()
|
||||
@@ -835,9 +866,10 @@
|
||||
(interactive)
|
||||
(let* ((room (alien-rpg--current-room))
|
||||
(connected (alien-rpg--connected-rooms room))
|
||||
(candidates (mapcar (lambda (r)
|
||||
(cons (alien-rpg--room-label r) (plist-get r :id)))
|
||||
connected))
|
||||
(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))
|
||||
@@ -849,9 +881,10 @@
|
||||
(defun alien-rpg-teleport ()
|
||||
"Teleport kamkoliv."
|
||||
(interactive)
|
||||
(let* ((candidates (mapcar (lambda (r)
|
||||
(cons (alien-rpg--room-label r) (plist-get r :id)))
|
||||
alien-rpg-rooms))
|
||||
(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))
|
||||
@@ -861,63 +894,18 @@
|
||||
(defun alien-rpg-find-room ()
|
||||
"Info o místnosti."
|
||||
(interactive)
|
||||
(let* ((candidates (mapcar (lambda (r)
|
||||
(cons (alien-rpg--room-label r) r))
|
||||
alien-rpg-rooms))
|
||||
(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)))
|
||||
(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)))
|
||||
(room (cdr (assoc choice candidates))))
|
||||
(with-current-buffer (get-buffer-create "*Alien RPG*")
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(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))))
|
||||
(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 ", "))))))
|
||||
(alien-rpg--insert-room-info room))
|
||||
(goto-char (point-min))
|
||||
(special-mode))
|
||||
(alien-rpg-view-mode))
|
||||
(switch-to-buffer "*Alien RPG*")))
|
||||
|
||||
(defun alien-rpg-find-path ()
|
||||
@@ -925,9 +913,10 @@
|
||||
(interactive)
|
||||
(let* ((start (plist-get alien-rpg-state :current-room))
|
||||
(start-room (alien-rpg--get-room start))
|
||||
(candidates (mapcar (lambda (r)
|
||||
(cons (alien-rpg--room-label r) (plist-get r :id)))
|
||||
alien-rpg-rooms))
|
||||
(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))
|
||||
@@ -958,16 +947,17 @@
|
||||
(insert "\n")))
|
||||
(insert "Cesta nenalezena.\n")))
|
||||
(goto-char (point-min))
|
||||
(special-mode))
|
||||
(alien-rpg-view-mode))
|
||||
(switch-to-buffer "*Alien RPG*")))
|
||||
|
||||
(defun alien-rpg-deck-overview ()
|
||||
"Přehled paluby."
|
||||
(interactive)
|
||||
(let* ((candidates (mapcar (lambda (d)
|
||||
(cons (format "%s %s" (plist-get d :id) (plist-get d :name))
|
||||
(plist-get d :id)))
|
||||
alien-rpg-decks))
|
||||
(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))
|
||||
@@ -983,7 +973,7 @@
|
||||
(plist-get r :name)
|
||||
(plist-get r :location)))))
|
||||
(goto-char (point-min))
|
||||
(special-mode))
|
||||
(alien-rpg-view-mode))
|
||||
(switch-to-buffer "*Alien RPG*")))
|
||||
|
||||
(defun alien-rpg-station-overview ()
|
||||
@@ -1004,7 +994,7 @@
|
||||
("E" (insert " ---\n"))
|
||||
("H" (insert " (průlezy G<->H)\n ---\n"))))))
|
||||
(goto-char (point-min))
|
||||
(special-mode))
|
||||
(alien-rpg-view-mode))
|
||||
(switch-to-buffer "*Alien RPG*")))
|
||||
|
||||
(defun alien-rpg-key-locations ()
|
||||
@@ -1030,7 +1020,7 @@ 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))
|
||||
(special-mode))
|
||||
(alien-rpg-view-mode))
|
||||
(switch-to-buffer "*Alien RPG*"))
|
||||
|
||||
(defun alien-rpg-status ()
|
||||
@@ -1109,7 +1099,7 @@ Průlezy G<->H: G3<->H3, G4<->H4, G7<->H7, G8<->H8, G9<->H9
|
||||
;; Signature
|
||||
(insert (format "Signature: %s\n" (or (plist-get ch :signature-item) "--"))))
|
||||
(goto-char (point-min))
|
||||
(special-mode))
|
||||
(alien-rpg-view-mode))
|
||||
(switch-to-buffer "*Alien RPG*")))
|
||||
|
||||
(defun alien-rpg-skills ()
|
||||
@@ -1141,7 +1131,7 @@ Průlezy G<->H: G3<->H3, G4<->H4, G7<->H7, G8<->H8, G9<->H9
|
||||
(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))
|
||||
(special-mode))
|
||||
(alien-rpg-view-mode))
|
||||
(switch-to-buffer "*Alien RPG*")))
|
||||
|
||||
;; --- Upravy stavu ---
|
||||
@@ -1199,7 +1189,8 @@ Průlezy G<->H: G3<->H3, G4<->H4, G7<->H7, G8<->H8, G9<->H9
|
||||
("Command" . (:skills :command))
|
||||
("Manipulation" . (:skills :manipulation))
|
||||
("Medical Aid" . (:skills :medical-aid))))
|
||||
(all-names (append (mapcar #'car st-choices) (mapcar #'car attr-choices) (mapcar #'car skill-choices)))
|
||||
(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))
|
||||
@@ -1232,18 +1223,19 @@ Průlezy G<->H: G3<->H3, G4<->H4, G7<->H7, G8<->H8, G9<->H9
|
||||
"Kolik kostek hodit — vyber dovednost."
|
||||
(interactive)
|
||||
(let* ((stress (plist-get alien-rpg-state :stress))
|
||||
(choices (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))
|
||||
(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))
|
||||
@@ -1256,7 +1248,7 @@ Průlezy G<->H: G3<->H3, G4<->H4, G7<->H7, G8<->H8, G9<->H9
|
||||
(insert (format "%d zlutych kostek (stress)\n" stress))
|
||||
(insert (format "%d kostek celkem\n" (+ base stress))))
|
||||
(goto-char (point-min))
|
||||
(special-mode))
|
||||
(alien-rpg-view-mode))
|
||||
(switch-to-buffer "*Alien RPG*")))
|
||||
|
||||
(defun alien-rpg-add-injury (injury)
|
||||
@@ -1332,9 +1324,295 @@ Průlezy G<->H: G3<->H3, G4<->H4, G7<->H7, G8<->H8, G9<->H9
|
||||
(dolist (n notes) (insert (format "%s\n" n)))
|
||||
(insert "(žádné poznámky)\n")))
|
||||
(goto-char (point-min))
|
||||
(special-mode))
|
||||
(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-manage-gear ()
|
||||
"Spravuj výbavu — odeber předmět."
|
||||
(interactive)
|
||||
(let ((extra (plist-get alien-rpg-state :extra-gear)))
|
||||
(if (not extra)
|
||||
(message "(žádná přidaná výbava)")
|
||||
(let* ((choice (completing-read "Odebrat výbavu: " extra nil t))
|
||||
(new-list (remove choice extra)))
|
||||
(setq alien-rpg-state (plist-put alien-rpg-state :extra-gear new-list))
|
||||
(alien-rpg--autosave)
|
||||
(message "Odebráno: %s" choice)))))
|
||||
|
||||
(defun alien-rpg-manage-weapon ()
|
||||
"Spravuj zbraně — odeber, uprav munici, nebo přepiš."
|
||||
(interactive)
|
||||
(let ((weapons (plist-get alien-rpg-state :weapons)))
|
||||
(if (not weapons)
|
||||
(message "(žádné zbraně)")
|
||||
(let* ((names (mapcar (lambda (w)
|
||||
(format "%s mod%+d/DMG%d/%s/%dks"
|
||||
(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)))
|
||||
weapons))
|
||||
(choice (completing-read "Zbraň: " names nil t))
|
||||
(idx (cl-position choice names :test #'string=))
|
||||
(weapon (nth idx weapons))
|
||||
(action (completing-read
|
||||
(format "%s: " (plist-get weapon :name))
|
||||
'("Munice +/-" "Odebrat" "Upravit") nil t)))
|
||||
(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
|
||||
(append (cl-subseq weapons 0 idx)
|
||||
(cl-subseq weapons (1+ idx)))))
|
||||
(alien-rpg--autosave)
|
||||
(message "Odebráno: %s" (plist-get weapon :name)))
|
||||
((string= action "Upravit")
|
||||
(let* ((name (read-string "Zbraň: " (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-manage-injury ()
|
||||
"Odeber zranění."
|
||||
(interactive)
|
||||
(let ((injuries (plist-get alien-rpg-state :injuries)))
|
||||
(if (not injuries)
|
||||
(message "(žádná zranění)")
|
||||
(let* ((choice (completing-read "Odebrat zranění: " injuries nil t))
|
||||
(new-list (remove choice injuries)))
|
||||
(setq alien-rpg-state (plist-put alien-rpg-state :injuries new-list))
|
||||
(alien-rpg--autosave)
|
||||
(message "Vyléčeno: %s" choice)))))
|
||||
|
||||
(defun alien-rpg-manage-condition ()
|
||||
"Odeber stav/podmínku."
|
||||
(interactive)
|
||||
(let ((conditions (plist-get alien-rpg-state :conditions)))
|
||||
(if (not conditions)
|
||||
(message "(žádné stavy)")
|
||||
(let* ((choice (completing-read "Odebrat stav: " conditions nil t))
|
||||
(new-list (remove choice conditions)))
|
||||
(setq alien-rpg-state (plist-put alien-rpg-state :conditions new-list))
|
||||
(alien-rpg--autosave)
|
||||
(message "Odebráno: %s" choice)))))
|
||||
|
||||
(defun alien-rpg-manage-armor ()
|
||||
"Odeber brnění."
|
||||
(interactive)
|
||||
(let ((armor (plist-get alien-rpg-state :armor)))
|
||||
(if (not armor)
|
||||
(message "(žádné brnění)")
|
||||
(when (y-or-n-p (format "Odebrat %s? " (plist-get armor :name)))
|
||||
(setq alien-rpg-state (plist-put alien-rpg-state :armor nil))
|
||||
(alien-rpg--autosave)
|
||||
(message "Brnění odebráno.")))))
|
||||
|
||||
(defun alien-rpg-manage-tiny-items ()
|
||||
"Odeber drobný předmět."
|
||||
(interactive)
|
||||
(let ((items (plist-get alien-rpg-state :tiny-items)))
|
||||
(if (not items)
|
||||
(message "(žádné drobné předměty)")
|
||||
(let* ((choice (completing-read "Odebrat: " items nil t))
|
||||
(new-list (remove choice items)))
|
||||
(setq alien-rpg-state (plist-put alien-rpg-state :tiny-items new-list))
|
||||
(alien-rpg--autosave)
|
||||
(message "Odebráno: %s" choice)))))
|
||||
|
||||
;; ====================================================================
|
||||
;; DISPATCH, HELP, VIEW MODE
|
||||
;; ====================================================================
|
||||
|
||||
(defvar alien-rpg--dispatch-commands
|
||||
'(("Brnění — přidat" . alien-rpg-add-armor)
|
||||
("Brnění — spravovat" . alien-rpg-manage-armor)
|
||||
("Deck přehled" . alien-rpg-deck-overview)
|
||||
("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)
|
||||
("Podmínka — přidat" . alien-rpg-add-condition)
|
||||
("Podmínka — odebrat" . alien-rpg-manage-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 — přidat" . alien-rpg-add-gear)
|
||||
("Výbava — spravovat" . alien-rpg-manage-gear)
|
||||
("Zbraň — přidat" . alien-rpg-add-weapon)
|
||||
("Zbraň — spravovat" . alien-rpg-manage-weapon)
|
||||
("Zranění — přidat" . alien-rpg-add-injury)
|
||||
("Zranění — odebrat" . alien-rpg-manage-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 ---\n")
|
||||
(insert "SPC G g Přidat výbavu\n")
|
||||
(insert "SPC G W Přidat zbraň\n")
|
||||
(insert "SPC G a Přidat brnění\n")
|
||||
(insert "SPC G j Přidat zranění\n")
|
||||
(insert "SPC G c Přidat podmínku\n\n")
|
||||
(insert "--- Inventář spravovat ---\n")
|
||||
(insert "SPC G v g Spravovat výbavu\n")
|
||||
(insert "SPC G v w Spravovat zbraně\n")
|
||||
(insert "SPC G v a Spravovat brnění\n")
|
||||
(insert "SPC G v j Spravovat zranění\n")
|
||||
(insert "SPC G v c Spravovat podmínky\n")
|
||||
(insert "SPC G v t Spravovat drobné věci\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
|
||||
;; ====================================================================
|
||||
@@ -1342,6 +1620,8 @@ Průlezy G<->H: G3<->H3, G4<->H4, G7<->H7, G8<->H8, G9<->H9
|
||||
(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
|
||||
@@ -1361,10 +1641,18 @@ Průlezy G<->H: G3<->H3, G4<->H4, G7<->H7, G8<->H8, G9<->H9
|
||||
:desc "Zbran" "W" #'alien-rpg-add-weapon
|
||||
:desc "Brneni" "a" #'alien-rpg-add-armor
|
||||
:desc "Stav/condition" "c" #'alien-rpg-add-condition
|
||||
:desc "Poznámka" "n" #'alien-rpg-add-note
|
||||
:desc "Poznamky" "N" #'alien-rpg-show-notes
|
||||
:desc "Pozn. místnost" "n" #'alien-rpg-add-room-note
|
||||
:desc "Poznamky" "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)))
|
||||
:desc "Načíst" "Q" #'alien-rpg-load-state
|
||||
(:prefix ("v" . "Inventář")
|
||||
:desc "Výbava" "g" #'alien-rpg-manage-gear
|
||||
:desc "Zbraně" "w" #'alien-rpg-manage-weapon
|
||||
:desc "Brnění" "a" #'alien-rpg-manage-armor
|
||||
:desc "Zranění" "j" #'alien-rpg-manage-injury
|
||||
:desc "Podmínky" "c" #'alien-rpg-manage-condition
|
||||
:desc "Drobné věci" "t" #'alien-rpg-manage-tiny-items))))
|
||||
|
||||
(provide 'alien-rpg)
|
||||
;;; alien-rpg.el ends here
|
||||
|
||||
Reference in New Issue
Block a user