(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] (-?> tilemap (. y) (. x))) (fn tile-at [x y tilemap] (let [itile (itile-at x y tilemap)] (match (type itile) :number (. tilemap.tileset itile) :table itile))) (fn set-itile-at [x y tilemap itile] (when (= nil (. tilemap y)) (tset tilemap y [])) (tset (. tilemap y) x itile)) (fn tile-at-overlay [x y tilemaps ?itilemap] (let [itilemap (or ?itilemap 1) tilemap (. tilemaps itilemap)] (when tilemap (let [tile (tile-at x y tilemap)] (if (= tile nil) (tile-at-overlay x y tilemaps (+ itilemap 1)) (values tile tilemap)))))) (fn new-tilemap [w h tileset ?itile] (local tilemap {: w : h : tileset}) (when (not= ?itile nil) (each [x y (all-coordinates w h)] (set-itile-at x y tilemap ?itile))) tilemap) (fn new-entitymap [w h] {: w : h :entities []}) (fn set-entity-at [x y tilemap entity] (set entity.x x) (set entity.y y) (table.insert tilemap.entities entity) (set-itile-at x y tilemap entity)) (fn remove-entity [tilemap entity] (lume.remove tilemap.entities entity) (set-itile-at entity.x entity.y tilemap)) (fn draw-tilemaps [x y tilemaps] (local base-tilemap (. tilemaps (length tilemaps))) (each [tx ty (all-coordinates base-tilemap.w base-tilemap.h)] (let [(tile tilemap) (tile-at-overlay tx ty tilemaps) xt (+ x (* tx dim.tilesize) (/ dim.tilesize 2)) yt (+ y (* ty dim.tilesize) (/ dim.tilesize 2))] (drawtile tile xt yt)))) (fn update-entitymap [tilemap ...] (each [_ entity (ipairs (lume.clone tilemap.entities))] (update entity ...))) (fn world-to-tile [vec] (-> vec ((vec-op #(math.floor (/ $1 dim.tilesize)))))) {: new-tilemap : itile-at : tile-at : set-itile-at : tile-at-overlay : draw-tilemaps : new-entitymap : set-entity-at : remove-entity : update-entitymap : world-to-tile : drawtile}