diff --git a/dialogue.lisp b/dialogue.lisp index c4c780c..3810492 100644 --- a/dialogue.lisp +++ b/dialogue.lisp @@ -39,8 +39,9 @@ Programming with nice tea! What a nice day this is. If you happen to be reading this, I hope your day is going well too! If not, have some tea on me: I’m paying. =w=" (and (listen) - (eq (getf (⌨:normalize-char-plist (⌨:read-char-plist)) :char) - #\return))) + (let ((input (getf (⌨:read-gamefied-char-plist) :semantic))) + (or (eq input '⌨:🆗) + (eq input '⌨:❎))))) @@ -138,9 +139,10 @@ data, using :SET and :TO of the DIALOGUE." (key (getf dialogue :set)) (data (getf dialogue :to))) (when (and key data) - (format *error-output* "[~A] ~A → ~A???~%" dialogue key data) - (setf (🌍:getf-entity-data map speaker key) data) - (format *error-output* "~A!!!!~%" (🌍:getf-entity-data map speaker :normal-face))))) + (setf (🌍:getf-entity-data map speaker key) data)))) +;; (format *error-output* "[~A] ~A → ~A???~%" dialogue key data) + +;; (format *error-output* "~A!!!!~%" (🌍:getf-entity-data map speaker :normal-face))))) (defun progress-line-delivery (dialogue) diff --git a/input.lisp b/input.lisp index b3144da..fc766a4 100644 --- a/input.lisp +++ b/input.lisp @@ -19,25 +19,47 @@ (defpackage :flora-search-aurora.input (:use :cl) (:nicknames :fsa.i :input :⌨) - (:export #:read-char-plist #:normalize-char-plist #:plist-char-p + (:export #:read-char-plist #:read-gamefied-char-plist + #:normalize-char-plist #:gameify-char-plist + #:plist-char-p :control :meta :shift - +qwerty-layout+ +dvorak-layout+)) + +qwerty-layout+ +dvorak-layout+ + +arrows-game-layout+ +wasd-game-layout+ +ijkl-game-layout+ + :↑ :← :→ :↓ :🆗 :❎)) (in-package :flora-search-aurora.input) - ;; Yup, they're hardcoded like this. Horrid, ain't it? ^_^ (defvar +qwerty-layout+ '(#\q #\Q #\w #\W #\e #\E #\r #\R #\t #\T #\y #\Y #\u #\U #\i #\I #\o #\O #\p #\P #\[ #\{ #\] #\} #\a #\A #\s #\S #\d #\D #\f #\F #\g #\G #\h #\H #\j #\J #\k #\K #\l #\L #\; #\: #\' #\" #\z #\Z #\x #\X #\c #\C #\v #\V #\b #\B #\n #\N #\m #\M #\, #\< #\. #\> #\/ #\?)) + (defvar +dvorak-layout+ '(#\' #\" #\, #\< #\. #\> #\p #\P #\y #\Y #\f #\F #\g #\G #\c #\C #\r #\R #\l #\L #\/ #\? #\= #\+ #\a #\A #\o #\O #\e #\E #\u #\U #\i #\I #\d #\D #\h #\H #\t #\T #\n #\N #\s #\S #\- #\_ #\; #\: #\q #\Q #\j #\J #\k #\K #\x #\X #\b #\B #\m #\M #\w #\W #\v #\V #\z #\Z)) +(defvar +arrows-game-layout+ + '((#\↑ . ↑)(#\← . ←)(#\↓ . ↓)(#\→ . →) + (#\a . 🆗)(#\z . 🆗)(#\space . 🆗)(#\return . 🆗) + (#\s . ❎)(#\x . ❎)(#\Esc . ❎))) + + +(defvar +wasd-game-layout+ + '((#\w . ↑)(#\a . ←)(#\s . ↓)(#\d . →) + (#\j . 🆗)(#\← . 🆗)(#\space . 🆗)(#\return . 🆗) + (#\k . ❎)(#\↓ . ❎)(#\Esc . ❎))) + + +(defvar +ijkl-game-layout+ + '((#\i . ↑)(#\j . ←)(#\k . ↓)(#\l . →) + (#\a . 🆗)(#\z . 🆗)(#\← . 🆗)(#\space . 🆗)(#\return . 🆗) + (#\s . ❎)(#\x . ❎)(#\↓ . ❎)(#\Esc . ❎))) + + (defun read-char-plist (&optional (stream *standard-input*)) "Reads a character directly from standard-input (sans buffering). Simple terminal escape codes (like arrow-keys) are translated into @@ -65,7 +87,7 @@ docstring of #'escape-code-to-character for more info." (defun normalize-char-plist (char-plist &optional (layout +qwerty-layout+)) - "Given a character input property list (as received from read-char-plist), + "Given a character input property list (as received from READ-CHAR-PLIST), massage the output into parsable, deescaped, QWERTY-according format." (let ((normalized (deescape-char-plist char-plist))) (setf (getf normalized :char) @@ -81,6 +103,26 @@ Not at all comprehensive, but probably-mostly-just-good-enough. ¯\_ (ツ)_/¯" char)) +(defun read-gamefied-char-plist + (&optional (stream *standard-input*) (layout +qwerty-layout+) (game-layout +arrows-game-layout+)) + "Read a character directly from standard-input, then translating its character into the QWERTY +equivalent, then parsing that character into semantic meaning. Results in a plist like so: + (:char #\w :semantic ↑ :modifier nil :escaped nil)" + (gameify-char-plist (normalize-char-plist (read-char-plist stream) layout) + game-layout)) + + +(defun gameify-char-plist (char-plist &optional (game-layout +arrows-game-layout+)) + "Given a character input plist (as received by READ-CHAR-PLIST), return a +char plist containing a :FUNCTION property, which contains one of several +semantic symbols that match up for menus/gameplay: ↑, →, ←, ↓, 🆗, or ❎." + (let ((semantic-value (cdr (assoc (getf char-plist :char) game-layout)))) + (if semantic-value + (append (list :semantic semantic-value) char-plist) + char-plist))) + + + (defun deescape-char-plist (char-plist) "Translate escaped characters into somewhat-semantically-adjacent characters, like left arrow-key (escaped D) into ← (“LEFTWARDS ARROW”)." diff --git a/overworld.lisp b/overworld.lisp index 6e8a5bd..b4a1e61 100644 --- a/overworld.lisp +++ b/overworld.lisp @@ -174,9 +174,6 @@ Used primarily in moving between different maps in an overworld state." map-b) - - - ;;; ——————————————————————————————————— ;;; Overworld logic @@ -216,10 +213,10 @@ Returns parameters to be used in the next invocation of OVERWORLD-STATE." (defun process-overworld-input (map) "Get and process any keyboard input, modifying the map or entities as necessary." (if (listen) - (let* ((input (⌨:normalize-char-plist (⌨:read-char-plist)))) - (cond + (let* ((input (⌨:read-gamefied-char-plist))) + (case (getf input :semantic) ;; Interacting with nearby characters/entities - ((…:plist= input '(:modifier nil :char #\return)) + ('⌨:🆗 (let* ((player (getf-entity map 'player)) (interactee (car (entities-near-entity player (gethash :entities map)))) (interactee-id (car interactee)) @@ -230,15 +227,15 @@ Returns parameters to be used in the next invocation of OVERWORLD-STATE." ;; The pause-menu… ;; ((plist = input '(:modifier nil :char #\Esc))) ;; Simple up-down-left-right movements - ((…:plist= input '(:modifier nil :char #\→)) + ('⌨:→ (move-player map :Δx 1)) - ((…:plist= input '(:modifier nil :char #\←)) + ('⌨:→ (move-player map :Δx -1)) - ((…:plist= input '(:modifier nil :char #\↑)) + ('⌨:↑ (move-player map :Δy -1)) - ((…:plist= input '(:modifier nil :char #\↓)) + ('⌨:↓ (move-player map :Δy 1)) - ('t + (otherwise (list :map map)))) (list :map map))) diff --git a/ui.lisp b/ui.lisp index 0ad2252..8ed67df 100644 --- a/ui.lisp +++ b/ui.lisp @@ -200,17 +200,19 @@ That is, 0 for non-selected items and 100 for selected items." (defun process-menu-input (menu-alist) "Get and process any keyboard input, modifying the menu alist as necessary." (if (listen) - (let* ((input (⌨:normalize-char-plist (⌨:read-char-plist))) + (let* ((input (⌨:read-gamefied-char-plist)) (selected-item (nth (selected-menu-item-position menu-alist) menu-alist)) (func (cdr (assoc 'function selected-item))) (return-val (assoc 'return selected-item))) - (case (getf input :char) - (#\→ (progn (select-right-menu-item menu-alist) - 't)) - (#\← (progn (select-left-menu-item menu-alist) - 't)) - (#\return + (case (getf input :semantic) + ('⌨:→ (progn (select-right-menu-item menu-alist) + 't)) + ('⌨:← (progn (select-left-menu-item menu-alist) + 't)) + ('⌨:❎ + nil) + ('⌨:🆗 (cond ((and func return-val) (apply func '()) (cdr return-val))