(local dim (require :game.dim)) (local util (require :lib.util)) (local {: all-coordinates : vec* : vec+ : vec-op} (util.require :game.helpers)) (local lume (require :lib.lume)) (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)) tile))))) (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 (tile-at-overlay tx ty tilemaps)] (when (and tile tile.draw) (tile.draw (+ x (* tx dim.tilesize) (/ dim.tilesize 2)) (+ y (* ty dim.tilesize) (/ dim.tilesize 2)) tile))))) (fn update-entitymap [tilemap ...] (each [_ entity (ipairs (lume.clone tilemap.entities))] (when entity.update (entity:update ...)))) (fn world-to-tile [vec] (-> vec ((vec-op #(math.floor (/ $1 dim.tilesize)))))) (fn colliding-tile-xy [vec dir] (-> vec (world-to-tile) (vec+ dir))) {: 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}