2020-09-12 12:09:28 +00:00
|
|
|
(ns ch.lyrion.rpg-engine.tilemap
|
|
|
|
(:require [clojure.java.io :as io]
|
|
|
|
[tile-soup.core :as ts]
|
|
|
|
[ch.lyrion.rpg-engine.validation :as validation]
|
|
|
|
[mount.core :refer [defstate]]))
|
|
|
|
|
|
|
|
(defn- load-raw-tileset [filename]
|
|
|
|
(->> filename
|
|
|
|
io/resource
|
|
|
|
slurp
|
|
|
|
(ts/parse :tile-soup.tileset/tileset)))
|
|
|
|
|
|
|
|
(defn- tileset-basemap [{:keys [attrs]}]
|
|
|
|
{:tileset/name (-> attrs :name keyword)
|
|
|
|
:tiles/width (:tilewidth attrs)
|
|
|
|
:tiles/height (:tileheight attrs)
|
|
|
|
:tiles/count (:tilecount attrs)})
|
|
|
|
|
|
|
|
(defn- tileset-tiles [tileset-map [tile & tiles]]
|
|
|
|
(case (:tag tile)
|
|
|
|
:tile (recur (update tileset-map :tiles conj
|
|
|
|
{:tile/id (-> tile :attrs :id)
|
|
|
|
:tile/width (-> tile :content first :attrs :width)
|
|
|
|
:tile/height (-> tile :content first :attrs :height)
|
|
|
|
:tile/src (-> tile :content first :attrs :source)})
|
|
|
|
tiles)
|
|
|
|
nil tileset-map
|
|
|
|
(recur tileset-map tiles)))
|
|
|
|
|
|
|
|
(defn- load-tileset* [filename]
|
|
|
|
{:post [(validation/validate :tileset %)]}
|
|
|
|
(let [raw-tileset (load-raw-tileset filename)]
|
|
|
|
(-> raw-tileset
|
|
|
|
tileset-basemap
|
|
|
|
(tileset-tiles (:content raw-tileset)))))
|
|
|
|
|
|
|
|
(defstate tilesets
|
|
|
|
:start (atom {}))
|
|
|
|
|
|
|
|
(defn load-tileset [filename]
|
|
|
|
(let [tileset (load-tileset* filename)]
|
|
|
|
(swap! tilesets assoc (:tileset/name tileset) tileset)
|
|
|
|
tileset))
|
|
|
|
|
|
|
|
;; Map
|
|
|
|
(defn- load-raw-tilemap [filename]
|
|
|
|
(->> filename
|
|
|
|
io/resource
|
|
|
|
slurp
|
|
|
|
ts/parse))
|
|
|
|
|
|
|
|
(defn- tilemap-basemap [{:keys [attrs]}]
|
|
|
|
{:map/width (:width attrs)
|
|
|
|
:map/height (:height attrs)
|
|
|
|
:tiles/width (:tilewidth attrs)
|
|
|
|
:tiles/height (:tileheight attrs)})
|
|
|
|
|
|
|
|
(defn- tilemap-layer [tilemap-map [entry & entries]]
|
|
|
|
(case (:tag entry)
|
|
|
|
:tileset (recur (update tilemap-map :map/tilesets conj
|
|
|
|
{:tileset/start-index (-> entry :attrs :firstgid)
|
|
|
|
:tileset/name (:tileset/name (load-tileset (-> entry :attrs :source)))})
|
|
|
|
entries)
|
2020-09-12 16:20:58 +00:00
|
|
|
:layer (recur (update tilemap-map :map/layers conj
|
2020-09-12 12:09:28 +00:00
|
|
|
{:layer/id (-> entry :attrs :id)
|
|
|
|
:layer/name (-> entry :attrs :name)
|
|
|
|
:layer/width (-> entry :attrs :width)
|
|
|
|
:layer/height (-> entry :attrs :height)
|
2020-09-12 16:20:58 +00:00
|
|
|
:layer/tiles (->> entry :content first :content first (map ts/tile-id->map))})
|
2020-09-12 12:09:28 +00:00
|
|
|
entries)
|
|
|
|
nil tilemap-map))
|
|
|
|
|
|
|
|
(defn load-tilemap* [filename]
|
2020-09-12 16:20:58 +00:00
|
|
|
{:post [(validation/validate :tilemap %)]}
|
2020-09-12 12:09:28 +00:00
|
|
|
(let [raw-tilemap (load-raw-tilemap filename)]
|
|
|
|
(-> raw-tilemap
|
|
|
|
tilemap-basemap
|
|
|
|
(tilemap-layer (:content raw-tilemap)))))
|
2020-09-12 16:20:58 +00:00
|
|
|
|
|
|
|
(defstate tilemap
|
|
|
|
:start (atom {}))
|
|
|
|
|
|
|
|
(defn load-tilemap [filename]
|
|
|
|
(let [tilemap-map (load-tilemap* filename)]
|
|
|
|
(reset! tilemap tilemap-map)
|
|
|
|
tilemap-map))
|