From 3a03af4b122421fd82b42c9036e14dd69ae5ce93 Mon Sep 17 00:00:00 2001 From: Daniel Ziltener Date: Sat, 12 Sep 2020 14:09:28 +0200 Subject: [PATCH] In the beginning there was darkness --- .clj-kondo/config.edn | 1 + .editorconfig | 11 ++++ .gitignore | 8 +++ README.md | 0 deps.edn | 16 +++++ planning.org | 9 +++ resources/test.tmx | 18 ++++++ resources/test.tsx | 16 +++++ resources/validators/tile.edn | 9 +++ resources/validators/tileset.edn | 14 +++++ src/ch/lyrion/rpg-engine/core.clj | 4 ++ src/ch/lyrion/rpg-engine/tilemap.clj | 77 +++++++++++++++++++++++++ src/ch/lyrion/rpg-engine/util.clj | 21 +++++++ src/ch/lyrion/rpg-engine/validation.clj | 29 ++++++++++ 14 files changed, 233 insertions(+) create mode 100644 .clj-kondo/config.edn create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 README.md create mode 100644 deps.edn create mode 100644 planning.org create mode 100644 resources/test.tmx create mode 100644 resources/test.tsx create mode 100644 resources/validators/tile.edn create mode 100644 resources/validators/tileset.edn create mode 100644 src/ch/lyrion/rpg-engine/core.clj create mode 100644 src/ch/lyrion/rpg-engine/tilemap.clj create mode 100644 src/ch/lyrion/rpg-engine/util.clj create mode 100644 src/ch/lyrion/rpg-engine/validation.clj diff --git a/.clj-kondo/config.edn b/.clj-kondo/config.edn new file mode 100644 index 0000000..6828faa --- /dev/null +++ b/.clj-kondo/config.edn @@ -0,0 +1 @@ +{:lint-as {mount.core/defstate clojure.core/def}} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c4ec5c9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..44969f3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*~ +*.jar +*.class +.nrepl-port +.cpcache/ +.cache/ +target/ +classes/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/deps.edn b/deps.edn new file mode 100644 index 0000000..71f2096 --- /dev/null +++ b/deps.edn @@ -0,0 +1,16 @@ +{:paths ["src" "resources" "classes"] + :deps {org.clojure/clojure {:mvn/version "1.10.1"} + org.clojure/data.xml {:mvn/version "0.0.8"} + + cljfx/cljfx {:git/url "https://github.com/cljfx/cljfx" + :sha "551150a8e9610ad007ead919c9456d1d34233706"} + tile-soup/tile-soup {;;:mvn/version "0.4.0" + :git/url "https://github.com/zilti/tile-soup" + :sha "fbe0abf9e05ed3a8553796f0713725bff18be856"} + datascript/datascript {:mvn/version "1.0.1"} + metosin/malli {:git/url "https://github.com/metosin/malli" + :sha "872be6a5ba8896649d82947e383c99118598d67e"} + mount/mount {:mvn/version "0.1.16"} + tolitius/mount-up {:mvn/version "0.1.3"}} + :aliases {:outdated {:extra-deps {olical/depot {:mvn/version "2.0.1"}} + :main-opts ["-m" "depot.outdated.main" "-a" "outdated" "--write"]}}} diff --git a/planning.org b/planning.org new file mode 100644 index 0000000..537f8c4 --- /dev/null +++ b/planning.org @@ -0,0 +1,9 @@ +#+AUTHOR: Daniel Ziltener +#+TITLE: RPG Engine Planning + +* Needed features +** Multi-layer tiling +** Smooth scrolling in all directions +** Smooth tile-wise character movement +** Dialog system +** Inventory system diff --git a/resources/test.tmx b/resources/test.tmx new file mode 100644 index 0000000..b5bed0a --- /dev/null +++ b/resources/test.tmx @@ -0,0 +1,18 @@ + + + + + +2,3,2147483651,2147483650,0,0,0,0,0,0, +1,1,1,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0 + + + diff --git a/resources/test.tsx b/resources/test.tsx new file mode 100644 index 0000000..257bf67 --- /dev/null +++ b/resources/test.tsx @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/resources/validators/tile.edn b/resources/validators/tile.edn new file mode 100644 index 0000000..8b99974 --- /dev/null +++ b/resources/validators/tile.edn @@ -0,0 +1,9 @@ +{:name :tile + :validator + [:map + [:tile/x int?] + [:tile/y int?] + [:tile/z int?] + [:tile/width int?] + [:tile/height int?] + [:tile/src string?]]} diff --git a/resources/validators/tileset.edn b/resources/validators/tileset.edn new file mode 100644 index 0000000..5f0dca8 --- /dev/null +++ b/resources/validators/tileset.edn @@ -0,0 +1,14 @@ +{:name :tileset + :validator + [:map + [:tileset/name keyword?] + [:tiles/width integer?] + [:tiles/height integer?] + [:tiles/count integer?] + [:tiles + [:sequential + [:map + [:tile/id integer?] + [:tile/width integer?] + [:tile/height integer?] + [:tile/src string?]]]]]} diff --git a/src/ch/lyrion/rpg-engine/core.clj b/src/ch/lyrion/rpg-engine/core.clj new file mode 100644 index 0000000..9893928 --- /dev/null +++ b/src/ch/lyrion/rpg-engine/core.clj @@ -0,0 +1,4 @@ +(ns ch.lyrion.rpg-engine.core + (:require [cljfx.api :as fx] + [datascript.core :as d])) + diff --git a/src/ch/lyrion/rpg-engine/tilemap.clj b/src/ch/lyrion/rpg-engine/tilemap.clj new file mode 100644 index 0000000..1b75104 --- /dev/null +++ b/src/ch/lyrion/rpg-engine/tilemap.clj @@ -0,0 +1,77 @@ +(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) + :layer (recur (update tilemap-map :layers conj + {:layer/id (-> entry :attrs :id) + :layer/name (-> entry :attrs :name) + :layer/width (-> entry :attrs :width) + :layer/height (-> entry :attrs :height) + :layer/tiles (-> entry :content first :content first)}) + entries) + nil tilemap-map)) + +(defn load-tilemap* [filename] + (let [raw-tilemap (load-raw-tilemap filename)] + (-> raw-tilemap + tilemap-basemap + (tilemap-layer (:content raw-tilemap))))) diff --git a/src/ch/lyrion/rpg-engine/util.clj b/src/ch/lyrion/rpg-engine/util.clj new file mode 100644 index 0000000..7a324cd --- /dev/null +++ b/src/ch/lyrion/rpg-engine/util.clj @@ -0,0 +1,21 @@ +(ns ch.lyrion.rpg-engine.util + (:require [clojure.java.io :as io]) + (:import (java.nio.file FileSystems + Files + Paths) + (java.net URI) + (java.util Collections))) + +(defn load-filelist-in-dir [dir] + (let [val-uri (->> dir + io/resource + .toString + (new URI)) + val-dir (if (= (.getScheme val-uri) "jar") + (-> val-uri + (FileSystems/newFileSystem (Collections/emptyMap)) + (.getPath dir)) + (Paths/get val-uri))] + (->> (Files/list val-dir) + .toArray + (map str)))) diff --git a/src/ch/lyrion/rpg-engine/validation.clj b/src/ch/lyrion/rpg-engine/validation.clj new file mode 100644 index 0000000..4df881d --- /dev/null +++ b/src/ch/lyrion/rpg-engine/validation.clj @@ -0,0 +1,29 @@ +(ns ch.lyrion.rpg-engine.validation + (:require [clojure.edn :as edn] + [ch.lyrion.rpg-engine.util :as util] + [mount.core :refer [defstate]] + [malli.core :as m])) + +(defn load-validation-file [path] + (let [valfile (-> path slurp edn/read-string)] + {(:name valfile) (:validator valfile)})) + +(defn load-validation-files [] + (let [files (util/load-filelist-in-dir "validators")] + (reduce #(merge %1 (load-validation-file %2)) + {} files))) + +(defstate registry + :start (merge + (m/class-schemas) + (m/comparator-schemas) + (m/base-schemas) + (m/default-schemas) + (m/predicate-schemas) + (load-validation-files))) + +(defn validate [spec value] + (m/validate spec value {:registry registry})) + +(defn validator [spec] + (m/validator spec {:registry registry}))