(local util (require :lib.util)) (local lume (require :lib.lume)) (local tiledraw (require :editor.tiledraw)) (local files (util.hot-table ...)) (local default-filename "bitsy/game.json") (local encoded-tile-fields [:gfx :mask]) (fn convert [tile field method] (local oldval (. tile field)) (when oldval (tset tile field (: oldval method))) tile) (fn convert-all [tile method] (each [_ field (ipairs encoded-tile-fields)] (convert tile field method)) tile) (fn tile-deserialize [tile] (match (type tile) :string {:gfx (tile:fromhex) :flags {}} :table (convert-all tile :fromhex))) (fn tile-serialize [tile] (convert-all (lume.clone tile) :tohex)) (fn deserialize [key value] (match key (where (or :tiles :portraits :font)) (tile-deserialize value) :levels (do (set value.map (value.map:fromhex)) value) _ value)) (fn serialize [key value] (match key (where (or :tiles :portraits :font)) (tile-serialize value) :levels (do (set value.map (value.map:tohex)) value) _ value)) (fn clone [v] (match (type v) :table (lume.clone v) _ v)) (fn filename [] (or files.filename default-filename)) (fn files.load [?filename] (when ?filename (set files.filename ?filename)) (set files.game (if (util.file-exists (filename)) (let [game (util.readjson (filename))] (each [k v (pairs game)] (tset game k (lume.map v #(deserialize k (clone $1))))) game) {:tiles [] :portraits [] :font [] :levels []})) files.game) (fn files.save [?filename] (when ?filename (set files.filename ?filename)) (let [game {}] (each [k v (pairs files.game)] (tset game k (lume.map v #(serialize k (clone $1))))) (util.writejson (filename) game))) (fn new-cache [game key] (let [spritegen (match key :font tiledraw.char-to-sprite :portraits tiledraw.portrait-to-sprite _ tiledraw.tile-to-sprite) gfx (. game key)] (tiledraw.TileCache gfx spritegen))) (fn files.cache [key] (when (= (?. files :tilecaches key) nil) (util.nested-tset files [:tilecaches key] (new-cache files.game key))) (. files.tilecaches key)) (fn files.reload [?filename] (files.load ?filename) (when files.tilecaches (each [key cache (pairs files.tilecaches)] (cache:load (. files.game key))))) (fn files.module [] (or files.game.module (: (filename) :match "^[^/]+"))) (when (= files.game nil) (files.load)) files.hot