diff --git a/dialogue.lisp b/dialogue.lisp index 66e8de2..c7dc056 100644 --- a/dialogue.lisp +++ b/dialogue.lisp @@ -20,7 +20,7 @@ (defpackage :flora-search-aurora.dialogue (:nicknames :fsa.dia :dialogue :πŸ’¬) (:use :cl) - (:export #:dialogue-state + (:export #:dialogue-state #:make-dialogue-state #:start-dialogue #:face #:say #:mumble #:move :normal-face :talking-face)) @@ -330,5 +330,12 @@ A state-function for use with STATE-LOOP." (dialogue-state-update map dialogue)) +(defun make-dialogue-state (map dialogue-list) + "Return a state-function for a section of dialogue, for use with STATE-LOOP." + (lambda (matrix &key (map map) (dialogue dialogue-list)) + (🌍:overworld-state-draw matrix map) + (dialogue-state matrix :map map :dialogue dialogue-list))) + + ;; Split a banana in two, bisection-fruit, ;; Yummy-yummy, toot-toot~ 🎡 diff --git a/engine.lisp b/engine.lisp new file mode 100644 index 0000000..653d755 --- /dev/null +++ b/engine.lisp @@ -0,0 +1,74 @@ +;;;; 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.ENGINE +;;;; The core of the game’s engine, the loop. Not much to see here other +;;;; than a loop. Honest! + + +(defpackage :flora-search-aurora.engine + (:nicknames :fsa.eng :engine :βš™) + (:export #:state-loop #:main) + (:use :cl)) + +(in-package :flora-search-aurora.engine) + + +(defun state-loop + (states &key (last-matrix (✎:make-screen-matrix)) (matrix (✎:make-screen-matrix)) (state-params nil)) + "Begin the game’s loop, which executes (henceforthly called) state-functions over and over again +until Hell freezes over and a new king reigns supreme. +Given a list of state-functions, STATES, it will execute the first function. +Each state-function must take at least a single parameter, a matrix of characters. A state-function +should edit this matrix in-place, replacing its elements with characters that will later be printed +to the terminal. +What the state-function returns is pretty important, having different repercussions: + * NIL β€” The function is removed from STATES, and so the next function in STATES will start + getting executed instead. + * NIL; List β€” The function is popped off STATES and the list is used as the new parameters for + the next function in STATES. + * Function β€” The function is pushed to the front of STATES, and so is executed instead of the + current function. + * List β€” The current function (front of STATES) continues to be executed with the given + list as a parameters list. +Make note to add a delay w SLEEP to your state functions, or… well, y’know. Your computer will +overheat, or something Β―\_(ツ)_/Β―" + (when states + (multiple-value-bind (state-result new-state-params) + (apply (car states) (cons matrix state-params)) ;; Run the latest-added update/draw loop + (✎:print-screen-matrix (✎:matrix-delta last-matrix matrix)) ;; Print its results. + (force-output) + (state-loop + (cond ((functionp state-result) + (cons state-result states)) + ((not state-result) + (cdr states)) + ('t states)) + :last-matrix matrix + :state-params + (cond ((not state-result) + new-state-params) + ((listp state-result) + state-result)))))) + + +(defun main (states) + "A toplevel-worthy function that configures rendering and kicks off the +game’s loop. Let’s get started!" + (cl-charms:with-curses () + (cl-charms:enable-raw-input :interpret-control-characters 't) + (✎:hide-cursor) + (✎:clear-screen) + (state-loop states))) diff --git a/flora-search-aurora.lisp b/flora-search-aurora.lisp index 8dff0d3..7e9818e 100644 --- a/flora-search-aurora.lisp +++ b/flora-search-aurora.lisp @@ -27,6 +27,7 @@ (load "overworld.tiled.lisp") (load "overworld.lisp") (load "dialogue.lisp") +(load "engine.lisp") (defpackage :flora-search-aurora (:nicknames :fsa :✿) @@ -39,72 +40,19 @@ (in-package :flora-search-aurora) -(defun literary-girl-dialogue-2 (map) - (print "OWO")) +(defparameter *literary-girl-dialogue* + (πŸ’¬:start-dialogue + (πŸ’¬:mumble "literary-girl" :en "...") + (πŸ’¬:say "player" :eo "Kielas apud la mar'?" + :en "How's the view?") + (πŸ’¬:face "player" "<.<") + (πŸ’¬:say "literary-girl" :eo "Kielas apud la ruinoj de via viv'?" + :en "How's your trainwreck of a life?") + (πŸ’¬:face "player" 'πŸ’¬:normal-face))) (defun literary-girl-dialogue (map) - (let - ((dialogue - (πŸ’¬:start-dialogue - (πŸ’¬:mumble "literary-girl" :en "...") - (πŸ’¬:say "player" :eo "Kielas apud la mar'?" - :en "How's the view?") - (πŸ’¬:face "player" "<.<") - (πŸ’¬:say "literary-girl" :eo "Kielas apud la ruinoj de via viv'?" - :en "How's your trainwreck of a life?") - (πŸ’¬:face "player" 'πŸ’¬:normal-face)))) - (lambda (matrix &key (map map) (dialogue dialogue)) - (🌍:overworld-state-draw matrix map) - (πŸ’¬:dialogue-state matrix :map map :dialogue dialogue)))) - - -(defun state-loop - (states &key (last-matrix (make-screen-matrix)) (matrix (make-screen-matrix)) (state-params nil)) - "Begin the game’s loop, which executes (henceforthly called) state-functions over and over again -until Hell freezes over and a new king reigns supreme. -Given a list of state-functions, STATES, it will execute the first function. -Each state-function must take at least a single parameter, a matrix of characters. A state-function -should edit this matrix in-place, replacing its elements with characters that will later be printed -to the terminal. -What the state-function returns is pretty important, having different repercussions: - * NIL β€” The function is removed from STATES, and so the next function in STATES will start - getting executed instead. - * NIL; List β€” The function is popped off STATES and the list is used as the new parameters for - the next function in STATES. - * Function β€” The function is pushed to the front of STATES, and so is executed instead of the - current function. - * List β€” The current function (front of STATES) continues to be executed with the given - list as a parameters list. -Make note to add a delay w SLEEP to your state functions, or… well, y’know. Your computer will -overheat, or something Β―\_(ツ)_/Β―" - (when states - (multiple-value-bind (state-result new-state-params) - (apply (car states) (cons matrix state-params)) ;; Run the latest-added update/draw loop - (✎:print-screen-matrix (✎:matrix-delta last-matrix matrix)) ;; Print its results. - (force-output) - (state-loop - (cond ((functionp state-result) - (cons state-result states)) - ((not state-result) - (cdr states)) - ('t states)) - :last-matrix matrix - :state-params - (cond ((not state-result) - new-state-params) - ((listp state-result) - state-result)))))) - - -(defun make-main-overworld-state () - "Return a state-function for the game’s overworld (the majority of the game), for use -with STATE-LOOP." - (lambda (matrix &rest args) - (apply #'🌍:overworld-state - (append (list matrix) - '(:map-path #p"/home/jaidyn/.local/src/games/flora search aurora/res/map.tmx") - args)))) + (make-dialogue-state map *literary-girl-dialogue*)) (defparameter *submenu* `(((LABEL :en "IDK") (selection . 100) (selected t)) @@ -113,7 +61,8 @@ with STATE-LOOP." (defparameter *main-menu* `(((LABEL :en "PLAY" :eo "EKLUDI") (selection . 100) (selected . t) - (return . ,(make-main-overworld-state))) + (return . ,(🌍:make-overworld-state + (format nil "~Ares/map.tmx" (uiop:getcwd))))) ((LABEL :en "SUBMENU" :eo "SUBMENUO") (return . ,(πŸ“‹:make-menu-state *submenu*))) ((LABEL :en "QUIT" :eo "REZIGNI") @@ -121,12 +70,10 @@ with STATE-LOOP." (defun main () - "A pathetic fascimile of a main loop. What does it do? WHAST DOES TI DODOO?" - (cl-charms:with-curses () - (cl-charms:enable-raw-input :interpret-control-characters 't) - (✎:hide-cursor) - (✎:clear-screen) - (state-loop (list (πŸ“‹:make-menu-state *main-menu*))))) + "A pathetic fascimile of a main loop. What does it do? WHAST DOES TI DODOO? +What a mysteryyy! You’ll have to check out the engine to uncover it. +engine.lisp, that is. Cheers! :D" + (βš™:main (list (πŸ“‹:make-menu-state *main-menu*)))) (main) ;; β€” Knock-knock diff --git a/overworld.lisp b/overworld.lisp index 794bde7..0b4a084 100644 --- a/overworld.lisp +++ b/overworld.lisp @@ -21,7 +21,7 @@ (:nicknames :fsa.o :overworld :🌍) (:use :cl :flora-search-aurora.overworld.tiled :flora-search-aurora.overworld.util) - (:export #:overworld-state #:overworld-state-draw + (:export #:overworld-state #:make-overworld-state #:overworld-state-draw #:world-coords->screen-coords #:getf-entity #:getf-entity-data #:move-entity-to #:move-entity @@ -250,3 +250,11 @@ A state-function for use with STATE-LOOP." (sleep .02) (overworld-state-draw matrix map) (overworld-state-update map)) + + +(defun make-overworld-state (map-path) + "Return a state-function for a a map, for use with STATE-LOOP." + (lambda (matrix &rest args) + (apply #'🌍:overworld-state + (append (list matrix :map-path map-path) + args))))