flora-search-aurora/overworld.util.lisp
Jaidyn Ann 74d713b76d Convert TMX maps to a parseable list
This allows embedding the map data directly
into the game system, instead of relying on
external files!
This’ll make distribution easier, for sure. =w=
2023-06-26 20:25:02 -05:00

88 lines
3.4 KiB
Common Lisp
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;;; Copyright © 2023, Jaidyn Ann <jadedctrl@posteo.at>
;;;;
;;;; 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 <https://www.gnu.org/licenses/>.
;;;; 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
#:map->plist #:plist->map
#:save-map-to-file))
(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))
(defun map->plist (map-hash)
"Convert a map(-HASH) into a friendly, property-list format!
Used by SAVE-MAP-TO-FILE."
(alexandria:hash-table-plist map-hash))
(defun plist->map (plist)
"Convert a map from a MAP->PLISTed PLIST into a normal
map hash-table, as used by the game."
(let ((hash (make-hash-table)))
;; Add the core map-data…
(setf (gethash :tiles hash) (getf plist :tiles))
(setf (gethash :top-tiles hash) (getf plist :top-tiles))
(setf (gethash :bump-map hash) (getf plist :bump-map))
(setf (gethash :entities hash) (getf plist :entities))
(setf (gethash :triggers hash) (getf plist :triggers))
;; And now the users data…
(setf (gethash :seconds hash) (getf plist :seconds))
(setf (gethash :day hash) (getf plist :day))
(setf (gethash :acts hash) (getf plist :acts))
(setf (gethash :knows hash) (getf plist :knows))
(setf (gethash :items hash) (getf plist :items))
hash))
(defun save-map-to-file (path map &optional (package ":FLORA-SEARCH-AURORA") (variable "*map*"))
"Given a map, generate source-code that corresponds to it."
(with-open-file (file-stream path :direction :output :if-exists :supersede)
(format file-stream "(in-package ~A)~%(defparameter ~A~% (🌍.…:plist->map~% (QUOTE ~S)))"
package variable (map->plist map))))