(local dim (require :game.dim)) (local util (require :lib.util)) (local {: all-coordinates : vec* : vec+ : vec-op} (util.require :game.helpers)) (local {: update} (util.require :game.entity)) (local {: defmulti : defmethod} (util.require :lib.multimethod)) (local lume (require :lib.lume)) (local drawtile (defmulti #(or $1.draw $1.entity $1.name) :drawtile ...)) (defmethod drawtile :default #nil) (fn itile-at [x y tilemap] (let [itile (-?> tilemap (. (+ y 1)) (: :sub (+ x 1) (+ x 1)))] (if (or (= itile nil) (= itile "")) " " itile))) (fn tile-at [x y tilemap tileset] (let [itile (itile-at x y tilemap)] (match (type itile) :string (. tileset itile) :table itile))) (fn set-itile-at [x y tilemap itile] (let [row (or (. tilemap (+ y 1)) "") row (.. row (string.rep " " (math.max 0 (- x (length row))))) pre (row:sub 1 x) post (row:sub (+ x 2)) row (.. pre itile post)] (tset tilemap (+ y 1) row))) (fn new-tilemap [w h ?itile] (local tilemap []) (when (not= ?itile nil) (each [x y (all-coordinates w h)] (set-itile-at x y tilemap (or ?itile " ")))) tilemap) (fn draw-tilemap [x y tilemap tileset] (each [irow row (ipairs tilemap)] (for [icol 1 (length row)] (let [tx (- icol 1) ty (- irow 1) tile (tile-at tx ty tilemap tileset) xt (+ x (* tx dim.tilesize) (/ dim.tilesize 2)) yt (+ y (* ty dim.tilesize) (/ dim.tilesize 2))] (when tile (drawtile tile xt yt)))))) (fn world-to-tile [vec] (-> vec ((vec-op #(math.floor (/ $1 dim.tilesize)))))) {: new-tilemap : itile-at : tile-at : set-itile-at : draw-tilemap : world-to-tile : drawtile}