diff --git a/flora-search-aurora.asd b/flora-search-aurora.asd index 13eef1f..d400eeb 100644 --- a/flora-search-aurora.asd +++ b/flora-search-aurora.asd @@ -8,6 +8,7 @@ (:file "display") (:file "input") (:file "menu") + (:file "settings") (:file "inventory") (:file "intermission") (:file "overworld.util") diff --git a/flora-search-aurora.lisp b/flora-search-aurora.lisp index 93743cc..0630611 100644 --- a/flora-search-aurora.lisp +++ b/flora-search-aurora.lisp @@ -13,7 +13,7 @@ ;;;; You should have received a copy of the GNU General Public License ;;;; along with this program. If not, see . -;;;; FLORA-SEARCH-AURORA +;;;; FLORA-SEARCH-AURORA ✿ ;;;; A simple TUI-game made for the text-flavoured LibreJam of 2023-06! ;;;; See: https://jamgaroo.xyz/jams/2 @@ -561,7 +561,7 @@ avoid triggering this." ;;; ——————————————————————————————————— -;;; Military base! +;;; Military-base! ;;; ——————————————————————————————————— (defun captain-snake-interact (map &optional entity-id) (make-dialogue-state @@ -962,30 +962,23 @@ avoid triggering this." Initializes the current instance of the game, and such." ;; We’ve gotta make fresh copies of the maps, in case the user’s restarted the game. ;; metacopy, I love you <3 <3 <3 - (defparameter *base-map* (🌍:plist->map (metacopy:copy-thing *base-map-plist*))) - (defparameter *casino-map* (🌍:plist->map (metacopy:copy-thing *casino-map-plist*))) - (defparameter *flashback-casino-map* (🌍:plist->map (metacopy:copy-thing *flashback-casino-map-plist*))) - (defparameter *flashback-school-map* (🌍:plist->map (metacopy:copy-thing *flashback-school-map-plist*))) - (defparameter *outdoors-map* (🌍:plist->map (metacopy:copy-thing *outdoors-map-plist*))) -;; (make-flashback-function (alexandria:random-elt (flashbacks)))) - (make-overworld-function *base-map*)) - - -(defun submenu () - `((:en "IDK" - :selection 100 :selected t) - (:en "GO BACK" - :drop 1))) + (lambda (matrix) + (defparameter *base-map* (🌍:plist->map (metacopy:copy-thing *base-map-plist*))) + (defparameter *casino-map* (🌍:plist->map (metacopy:copy-thing *casino-map-plist*))) + (defparameter *flashback-casino-map* (🌍:plist->map (metacopy:copy-thing *flashback-casino-map-plist*))) + (defparameter *flashback-school-map* (🌍:plist->map (metacopy:copy-thing *flashback-school-map-plist*))) + (defparameter *outdoors-map* (🌍:plist->map (metacopy:copy-thing *outdoors-map-plist*))) + ;; (make-flashback-function (alexandria:random-elt (flashbacks)))) + (make-overworld-state *casino-map*))) (defun main-menu () - `((:en "PLAY" :eo "EKLUDI" - :selection 100 :selected t + `((:en "Play" :eo "Ekludi" + :selection 50 :selected t :function ,(start-game-function)) - (:en "SUBMENU" :eo "SUBMENUO" :row 1 - :function ,(📋:make-menu-function (submenu))) - (:en "TERURE" :eo "BADLY" :row 1) - (:en "QUIT" :eo "REZIGNI" :row 2 + (:en "Settings" :eo "Agordoj" :row 1 + :function ,(🔧:make-settings-menu-function)) + (:en "Give in" :eo "Cedi" :row 2 :drop 1))) diff --git a/input.lisp b/input.lisp index bda93b1..05f7d2e 100644 --- a/input.lisp +++ b/input.lisp @@ -13,7 +13,7 @@ ;;;; You should have received a copy of the GNU General Public License ;;;; along with this program. If not, see . -;;;; FLORA-SEARCH-AURORA.INPUT +;;;; FLORA-SEARCH-AURORA.INPUT ⌨ ;;;; All input-related voodoo goes here: Input reading, translating, parsing, etc. (in-package :flora-search-aurora.input) @@ -58,6 +58,10 @@ +numpad-game-layout+)) +(defparameter *keyboard* +qwerty-layout+) +(defparameter *controls* +arrows-game-layout+) + + (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 @@ -84,7 +88,7 @@ docstring of #'escape-code-to-character for more info." (list :char the-char :modifier modifier :escaped escaped)))) -(defun normalize-char-plist (char-plist &optional (layout +qwerty-layout+)) +(defun normalize-char-plist (char-plist &optional (layout *keyboard*)) "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))) @@ -102,7 +106,7 @@ Not at all comprehensive, but probably-mostly-just-good-enough. ¯\_ (ツ)_/¯" (defun read-gamefied-char-plist - (&optional (stream *standard-input*) (layout +qwerty-layout+) (game-layout +arrows-game-layout+)) + (&optional (stream *standard-input*) (layout *keyboard*) (game-layout *controls*)) "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)" @@ -110,7 +114,7 @@ equivalent, then parsing that character into semantic meaning. Results in a plis game-layout)) -(defun gameify-char-plist (char-plist &optional (game-layout +arrows-game-layout+)) +(defun gameify-char-plist (char-plist &optional (game-layout *keyboard*)) "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 ❎." @@ -120,7 +124,6 @@ semantic symbols that match up for menus/gameplay: ↑, →, ←, ↓, 🆗, or 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/menu.lisp b/menu.lisp index 5263150..b6e7fdd 100644 --- a/menu.lisp +++ b/menu.lisp @@ -13,7 +13,7 @@ ;;;; You should have received a copy of the GNU General Public License ;;;; along with this program. If not, see . -;;;; FLORA-SEARCH-AURORA.UI +;;;; FLORA-SEARCH-AURORA.MENU 📋 ;;;; Generic menu-making, displaying, and management. ;;;; Let's get to it, we're on a deadline! @@ -168,7 +168,7 @@ That is, 0 for non-selected items and 100 for selected items." (select-right-menu-item menu-plist) 't)) ('⌨:❎ - nil) + (list :drop 1)) ('⌨:🆗 (if (getf selected-item :exec) (apply (getf selected-item :exec) '()) diff --git a/overworld.lisp b/overworld.lisp index 0b23935..986ae36 100644 --- a/overworld.lisp +++ b/overworld.lisp @@ -13,7 +13,7 @@ ;;;; You should have received a copy of the GNU General Public License ;;;; along with this program. If not, see . -;;;; FLORA-SEARCH-AURORA.OVERWORLD +;;;; FLORA-SEARCH-AURORA.OVERWORLD 🌍 ;;;; All game-functions and data relating to the “overworld” (that is, ;;;; the primary gameplay, the RPG-ish-ish bits). @@ -212,7 +212,17 @@ Returns parameters to be used in the next invocation of OVERWORLD-STATE." (apply (…:string->symbol interaction) (list map interactee-id)) (list :parameters (list :map map))))) ('⌨:❎ - (list :function (🎒:make-inventory-state map))) + (list :function + (📋:make-menu-function + `((:en "Continue" :eo "Malpaŭzigi" + :drop 1 :selected t :selection 50) + (:en "Backpack" :eo "Sako" + :function ,(🎒:make-inventory-function map) + :drop 1) + (:en "Settings" :eo "Agordoj" + :function ,(🔧:make-settings-menu-function)) + (:en "Give up" :eo "Rezigni" + :drop 3))))) ;; Simple up-down-left-right movements ('⌨:→ (move-player map :Δx 1)) @@ -401,7 +411,7 @@ plist containing a character (:CHAR) and :X & :Y coordinates." ;;; ——————————————————————————————————— (defun overworld-state (matrix &key map (Δt .02)) - "Render the given map to the matrix and take user-input — for one frame. + "Render the given map to the MATRIX and take user-input — for one frame. A state-function for use with STATE-LOOP." (sleep Δt) (overworld-state-draw matrix map) @@ -409,7 +419,12 @@ A state-function for use with STATE-LOOP." (defun make-overworld-function (map) - "Return a state-function for a a map, for use with STATE-LOOP." + "Return a state-function for a a MAP, for use with STATE-LOOP." (lambda (matrix &key (map map)) (apply #'🌍:overworld-state (list matrix :map map)))) + + +(defun make-overworld-state (map) + "Return a state-plist for a a MAP, for use with STATE-LOOP." + (list :function (make-overworld-function map))) diff --git a/packages.lisp b/packages.lisp index 050a1d0..e9e78b8 100644 --- a/packages.lisp +++ b/packages.lisp @@ -23,8 +23,8 @@ #:incf-0 #:at-least #:at-most #:string->symbol - #:system-language #:langcode->keysym #:getf-lang)) - + #:system-language #:langcode->keysym #:getf-lang + :*language*)) (defpackage :flora-search-aurora.input (:use :cl) @@ -36,7 +36,8 @@ :control :meta :shift +qwerty-layout+ +dvorak-layout+ +arrows-game-layout+ +wasd-game-layout+ +ijkl-game-layout+ - :↑ :← :→ :↓ :↰ :↱ :↲ :↳ :🆗 :❎)) + :↑ :← :→ :↓ :↰ :↱ :↲ :↳ :🆗 :❎ + :*keyboard* :*controls*)) (defpackage :flora-search-aurora.display (:nicknames :fsa.dsp :display :✎) @@ -53,6 +54,12 @@ #:selected-menu-item :label :selection :selected)) +(defpackage :flora-search-aurora.settings + (:nicknames :fsa.set :settings :🔧) + (:use :cl) + (:export #:make-settings-menu-function #:settings-menu)) + + (defpackage :flora-search-aurora.dialogue (:nicknames :fsa.dia :dialogue :💬) (:use :cl) @@ -63,7 +70,7 @@ (defpackage :flora-search-aurora.inventory (:nicknames :fsa.inv :inventory :🎒) (:use :cl) - (:export #:inventory-state #:make-inventory-state)) + (:export #:inventory-state #:make-inventory-function)) (defpackage :flora-search-aurora.intermission (:nicknames :fsa.int :intermission :🎭) @@ -72,19 +79,21 @@ :make-intermission-function)) (defpackage :flora-search-aurora.overworld.util - (:nicknames :fsa.o.u :overworld.util :🌍.…) + (:nicknames :fsa.ovr.… :overworld.util :🌍.…) (:use :cl) (:export #:coords->symbol #:symbol->coords #:world-coords->screen-coords #:world-coords-chunk #:map->plist #:plist->map - #:save-map-to-file)) + #:save-map-to-file + :*language*)) (defpackage :flora-search-aurora.overworld - (:nicknames :fsa.o :overworld :🌍) + (:nicknames :fsa.ovr :overworld :🌍) (:use :cl :flora-search-aurora.overworld.util) - (:export #:overworld-state #:overworld-state-draw #:make-overworld-function + (:export #:make-overworld-state #:make-overworld-function + #:overworld-state #:overworld-state-draw #:merge-maps #:world-coords->screen-coords #:getf-entity #:getf-entity-data #:removef-entity diff --git a/settings.lisp b/settings.lisp new file mode 100644 index 0000000..2c69180 --- /dev/null +++ b/settings.lisp @@ -0,0 +1,92 @@ +;;;; Copyright © 2023, Jaidyn Ann +;;;; +;;;; This program is free software: you can redistribute it and/or +;;;; modify it under the terms of the GNU General Public License as +;;;; published by the Free Software Foundation, either version 3 of +;;;; the License, or (at your option) any later version. +;;;; +;;;; This program is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;;; GNU General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with this program. If not, see . + +;;;; FLORA-SEARCH-AURORA.SETTINGS 🔧 +;;;; Guess whatttt? Settings, that’s what. =w= +;;;; How riveting! + +(in-package :flora-search-aurora.settings) + + +(defun make-controls-function (controls) + "Simple state-function (for use with STATE-LOOP's state plists) that sets the +keyboard controls to the given CONTROLS." + (lambda (matrix) + (setq ⌨:*controls* controls) + (list :drop 1))) + + +(defun make-keyboard-function (layout) + "Simple state-function (for use with STATE-LOOP's state plists) that sets the +keyboard layout to the given LAYOUT." + (lambda (matrix) + (setq ⌨:*keyboard* layout) + (list :drop 1))) + + +(defun make-language-function (language) + "Simple state-function (for use with STATE-LOOP's state plists) that sets the +game language to the given LANGUAGE." + (lambda (matrix) + (setq …:*language* language) + (list :drop 1))) + + +(defun keyboard-menu () + `((:en "QWERTY" + :selection 50 :selected t + :function ,(make-keyboard-function ⌨:+qwerty-layout+) + :drop 1) + (:en "Dvorak" + :function ,(make-keyboard-function ⌨:+dvorak-layout+) + :drop 1) + (:en "Arrows" :eo "Sagoj" + :function ,(make-controls-function ⌨:+arrows-game-layout+) + :row 1 :drop 1) + (:en "WASD" + :function ,(make-controls-function ⌨:+wasd-game-layout+) + :row 1 :drop 1) + (:en "IJKL" :eo "IJKL" + :function ,(make-controls-function ⌨:+ijkl-game-layout+) + :row 1 :drop 1))) + + +(defun language-menu () + `((:en "Esperanto" + :selected t :selection 50 + :function ,(make-language-function :eo) + :drop 1) + (:en "English" + :function ,(make-language-function :en) + :row 1 :drop 1))) + + +(defun settings-menu () + `((:en "Keyboard" :eo "Klavararanĝo" + :selection 50 :selected t + :function + ,(📋:make-menu-function (keyboard-menu)) + :drop 1) + (:en "Language" :eo "Lingvo" + :function ,(📋:make-menu-function (language-menu)) + :drop 1) + (:en "Back" :eo "Reiri" + :drop 1))) + + +(defun make-settings-menu-function () + "Create a menu state-function for use with STATE-LOOP, displaying settings +and allowing the user to modify them. Pretty self-explanatory, tbh." + (📋:make-menu-function (settings-menu))) diff --git a/util.lisp b/util.lisp index 4cb5c65..b3005c4 100644 --- a/util.lisp +++ b/util.lisp @@ -153,8 +153,11 @@ if the language is among the supported. Otherwise, nil." :en)) -(defun getf-lang (plist &optional (language (system-language)) (fallback-lang :en)) - "With a plist containing keys of language-codes, return the property either fitting the +(defun getf-lang (plist &key language (fallback-lang :en)) + "With a PLIST containing keys of language-codes, return the property either fitting the preferred LANGUAGE, or the backup FALLBACK-LANG (if LANGUAGE’s is NIL)." - (or (getf plist language) + (or (getf plist (or language (ignore-errors *language*) (system-language))) (getf plist fallback-lang))) + + +(defparameter *language* (…:system-language))