diff --git a/flora-search-aurora.lisp b/flora-search-aurora.lisp index c122c73..189b7a1 100644 --- a/flora-search-aurora.lisp +++ b/flora-search-aurora.lisp @@ -22,7 +22,8 @@ (load "input.lisp") (load "display.lisp") (load "ui.lisp") -(load "tiled.lisp") +(load "overworld.util.lisp") +(load "overworld.tiled.lisp") (load "overworld.lisp") (defpackage :flora-search-aurora @@ -33,11 +34,12 @@ (in-package :flora-search-aurora) +(defun literary-girl-dialogue-2 (map) + (print "OWO")) (defun literary-girl-dialogue (map) - (print "uwu")) - - + (print "uwu") + (setf (getf-entity-data map 'literary-girl :interact) "literary-girl-dialogue-2")) (defun state-loop diff --git a/overworld.lisp b/overworld.lisp index 313146b..e7e936f 100644 --- a/overworld.lisp +++ b/overworld.lisp @@ -18,11 +18,13 @@ ;;;; the primary gameplay, the RPG-ish-ish bits). (defpackage :flora-search-aurora.overworld + (:nicknames :fsa.o :overworld) (:use :cl - :flora-search-aurora.input :flora-search-aurora.display - :flora-search-aurora.overworld.tiled - :flora-search-aurora.ui) - (:export #:overworld-state :player)) + :flora-search-aurora.input :flora-search-aurora.display :flora-search-aurora.ui + :flora-search-aurora.overworld.tiled :flora-search-aurora.overworld.util) + (:export #:overworld-state + #:getf-entity #:getf-entity-data + :player)) (in-package :flora-search-aurora.overworld) diff --git a/tiled.lisp b/overworld.tiled.lisp similarity index 78% rename from tiled.lisp rename to overworld.tiled.lisp index 0f3ffcb..6bafbca 100644 --- a/tiled.lisp +++ b/overworld.tiled.lisp @@ -13,43 +13,54 @@ ;;;; You should have received a copy of the GNU General Public License ;;;; along with this program. If not, see . -;;;; FLORA-SEARCH-AURORA.OVERWORLD -;;;; All game-functions and data relating to the “overworld” (that is, -;;;; the primary gameplay, the RPG-ish-ish bits). +;;;; FLORA-SEARCH-AURORA.OVERWORLD.TILED +;;;; Import a Tiled-format (TMX) map into the hash-table/plist/alist format +;;;; used by the overworld. (defpackage :flora-search-aurora.overworld.tiled - (:use :cl) - (:export #:load-map - #:world-coords-chunk #:world-coords->screen-coords)) + (:nicknames :fsa.o.t :overworld.tiled) + (:use :cl + :flora-search-aurora.overworld.util) + (:export #:load-map)) (in-package :flora-search-aurora.overworld.tiled) ;;; ——————————————————————————————————— -;;; Tiled maps → Map lists +;;; Misc. utility ;;; ——————————————————————————————————— -(defun load-map (map-file) - "Parse a map-file into an plist of its data. This consists of: - :BUMP-MAP, an alist of tiles (keyed by chunk) in a “collidable” layer - :TILES, an alist of visible tiles (keyed by chunk). - :ENTITIES, a list of entity plists." - (let ((tile-chunks '()) - (bump-map '()) - (entities '()) - (hash (make-hash-table))) - (mapcar (lambda (layer) - (typecase layer - (cl-tiled.data-types:tile-layer - (when (gethash "colliding" (cl-tiled:properties layer) #'string-equal) - (setf bump-map (tile-layer-chunks layer bump-map))) - (setf tile-chunks (tile-layer-chunks layer tile-chunks))) - (cl-tiled.data-types:object-layer - (setf entities (object-layer-entities layer entities))))) - (cl-tiled:map-layers (cl-tiled:load-map map-file))) - (setf (gethash :tiles hash) tile-chunks) - (setf (gethash :bump-map hash) bump-map) - (setf (gethash :entities hash) entities) - hash)) +(defun collect-items-into-groups (list key-function &key (groups '())) + "Given a LIST of items and a function categorizing an individual item +(returning a “category” symbol for any given item), return an sorted +associative list." + (loop for item in list + do (let ((key (apply key-function (list item)))) + (setf (assoc-utils:aget groups key) + (append (assoc-utils:aget groups key) + (list item))))) + groups) + + + +;;; ——————————————————————————————————— +;;; Tile-layer parsing (graphics) +;;; ——————————————————————————————————— +(defun tiled-cell->cell (tiled-cell) + "Convert a Tiled cell into a cell plist." + (list :coords (list :x (cl-tiled:cell-column tiled-cell) + :y (cl-tiled:cell-row tiled-cell)) + :char (tile-character (cl-tiled:cell-tile tiled-cell)))) + + +(defun tile-layer-chunks (layer &optional (chunks '())) + "Given a Tiled tile-layer (that is, graphics of the map), parse it into an +alist of Tiled cell “chunks”." + (let ((cells (mapcar #'tiled-cell->cell (cl-tiled:layer-cells layer)))) + (collect-items-into-groups + cells + (lambda (cell) + (world-coords-chunk (getf cell :coords))) + :groups chunks))) (defun object-layer-entities (layer &optional (entities '())) @@ -78,6 +89,17 @@ 'left)))) + +;;; ——————————————————————————————————— +;;; Tile-layer parsing (graphics) +;;; ——————————————————————————————————— +(defun tiled-cell->cell (tiled-cell) + "Convert a Tiled cell into a cell plist." + (list :coords (list :x (cl-tiled:cell-column tiled-cell) + :y (cl-tiled:cell-row tiled-cell)) + :char (tile-character (cl-tiled:cell-tile tiled-cell)))) + + (defun tile-layer-chunks (layer &optional (chunks '())) "Given a Tiled tile-layer (that is, graphics of the map), parse it into an alist of Tiled cell “chunks”." @@ -89,13 +111,6 @@ alist of Tiled cell “chunks”." :groups chunks))) -(defun tiled-cell->cell (tiled-cell) - "Convert a Tiled cell into a cell plist." - (list :coords (list :x (cl-tiled:cell-column tiled-cell) - :y (cl-tiled:cell-row tiled-cell)) - :char (tile-character (cl-tiled:cell-tile tiled-cell)))) - - (defun layer-objects (layer) "Return all Tiled objects in the given object layer." (slot-value layer 'cl-tiled.data-types::objects)) @@ -113,42 +128,27 @@ with 15 characters-per-line." ;;; ——————————————————————————————————— -;;; Misc. utility +;;; Tiled maps → Map lists ;;; ——————————————————————————————————— -(defun collect-items-into-groups (list key-function &key (groups '())) - "Given a LIST of items and a function categorizing an individual item -(returning a “category” symbol for any given item), return an sorted -associative list." - (loop for item in list - do (let ((key (apply key-function (list item)))) - (setf (assoc-utils:aget groups key) - (append (assoc-utils:aget groups key) - (list item))))) - groups) - - -(defun world-coords->screen-coords (world-coords &key (chunk-width 72) (chunk-height 20)) - "Given a set of “world” coordinates, determine where this spot would be on the screen. -The world is split into screen-sized “chunks” to this end. -— Chester P. Runk" - (let* ((chunk-x (floor (/ (getf world-coords :x) - chunk-width))) - (chunk-y (floor (/ (getf world-coords :y) - chunk-height))) - (x (- (getf world-coords :x) (* chunk-x chunk-width))) - (y (- (getf world-coords :y) (* chunk-y chunk-height)))) - (list :x x - :y y - :chunk (coords->symbol chunk-x chunk-y)))) - - -(defun world-coords-chunk (coords) - (getf (world-coords->screen-coords coords) :chunk)) - - -(defun coords->symbol (x y) - (intern (format nil "~A,~A" x y))) - - -(defun symbol->coords (coords-symbol) - (str:split #\, (symbol-name coords-symbol))) +(defun load-map (map-file) + "Parse a map-file into an plist of its data. This consists of: + :BUMP-MAP, an alist of tiles (keyed by chunk) in a “collidable” layer + :TILES, an alist of visible tiles (keyed by chunk). + :ENTITIES, a list of entity plists." + (let ((tile-chunks '()) + (bump-map '()) + (entities '()) + (hash (make-hash-table))) + (mapcar (lambda (layer) + (typecase layer + (cl-tiled.data-types:tile-layer + (when (gethash "colliding" (cl-tiled:properties layer) #'string-equal) + (setf bump-map (tile-layer-chunks layer bump-map))) + (setf tile-chunks (tile-layer-chunks layer tile-chunks))) + (cl-tiled.data-types:object-layer + (setf entities (object-layer-entities layer entities))))) + (cl-tiled:map-layers (cl-tiled:load-map map-file))) + (setf (gethash :tiles hash) tile-chunks) + (setf (gethash :bump-map hash) bump-map) + (setf (gethash :entities hash) entities) + hash)) diff --git a/overworld.util.lisp b/overworld.util.lisp new file mode 100644 index 0000000..13c5303 --- /dev/null +++ b/overworld.util.lisp @@ -0,0 +1,53 @@ +;;;; 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.OVERWORLD.UTIL +;;;; Utility functions used by multiple overworld packages (overworld.tiled & overworld). + +(defpackage :flora-search-aurora.overworld.util + (:nicknames :fsa.o.u :overworld.util) + (:use :cl) + (:export #:coords->symbol #:symbol->coords + #:world-coords->screen-coords + #:world-coords-chunk)) + +(in-package :flora-search-aurora.overworld.util) + + +(defun coords->symbol (x y) + (intern (format nil "~A,~A" x y))) + + +(defun symbol->coords (coords-symbol) + (str:split #\, (symbol-name coords-symbol))) + + +(defun world-coords->screen-coords (world-coords &key (chunk-width 72) (chunk-height 20)) + "Given a set of “world” coordinates, determine where this spot would be on the screen. +The world is split into screen-sized “chunks” to this end. +— Chester P. Runk" + (let* ((chunk-x (floor (/ (getf world-coords :x) + chunk-width))) + (chunk-y (floor (/ (getf world-coords :y) + chunk-height))) + (x (- (getf world-coords :x) (* chunk-x chunk-width))) + (y (- (getf world-coords :y) (* chunk-y chunk-height)))) + (list :x x + :y y + :chunk (coords->symbol chunk-x chunk-y)))) + + +(defun world-coords-chunk (coords) + (getf (world-coords->screen-coords coords) :chunk))