(local lume (require :lib.lume)) (local map (require :game.tilemap)) (local tileset (require :game.tiles)) (local state (require :game.state)) (local Bomb (require :game.entities.bomb)) (local Rules {}) (fn Rules.tile-at [[x y]] (map.tile-at-overlay x y [state.bombs state.map])) (local tile-at Rules.tile-at) (fn Rules.place-bomb [[x y]] (when (. (tile-at [x y]) :empty) (map.set-entity-at x y state.bombs (Bomb.new)))) (fn Rules.clear-bomb [bomb] (map.remove-entity state.bombs bomb)) (fn explode-in-dir [x y dx dy len] (when (and (>= x 0) (< x state.map.w) (>= y 0) (< y state.map.h)) (let [tile (tile-at [x y])] (if tile.empty (do (map.set-entity-at x y state.bombs (Bomb.new-explosion)) (when (> len 0) (explode-in-dir (+ x dx) (+ y dy) dx dy (- len 1)))) (= tile.state :ticking) (Bomb.explode tile Rules) tile.breakable (map.set-itile-at x y state.map (tileset.itile-named state.map.tileset :empty)))))) (fn Rules.explode-bomb [bomb] (each [_ [dx dy] (ipairs [[-1 0] [1 0] [0 -1] [0 1]])] (explode-in-dir (+ bomb.x dx) (+ bomb.y dy) dx dy 1))) (fn Rules.generate-maze [tilemap] (let [empty (tileset.itile-named tilemap.tileset :empty) wall (tileset.itile-named tilemap.tileset :strongwall) weak (tileset.itile-named tilemap.tileset :weakwall)] (for [x 0 (- tilemap.w 1)] (for [y 0 (- tilemap.h 1)] (map.set-itile-at x y tilemap (if (or (= y 0) (= y (- tilemap.h 1)) (= x 0) (= x (- tilemap.w 1))) wall (and (= (% x 2) 0) (= (% y 2) 0)) wall (< (math.random) 0.3) weak empty)))))) Rules