diff --git a/game/engine/Savefile.lua b/game/engine/Savefile.lua index a6adb5b4e4d2f9036b09ccbe4e8ad60b144accee..ad1a0e174315c78862b8d44673ee9faee818bf07 100644 --- a/game/engine/Savefile.lua +++ b/game/engine/Savefile.lua @@ -99,6 +99,20 @@ function _M:saveGame(game) game:unregisterDialog(popup) end +--- Save a zone +function _M:saveZone(zone) + fs.mkdir(self.save_dir) + + local popup = Dialog:simplePopup("Saving zone", "Please wait while saving the zone...") + core.display.forceRedraw() + + local zip = fs.zipOpen(self.save_dir..("zone-%s.teaz"):format(zone.short_name)) + self:saveObject(zone, zip) + zip:close() + + game:unregisterDialog(popup) +end + --- Save a level function _M:saveLevel(level) fs.mkdir(self.save_dir) @@ -172,6 +186,30 @@ function _M:loadGame() return loadedGame end +--- Loads a zone +function _M:loadZone(zone) + local path = fs.getRealPath(self.save_dir..("zone-%s.teaz"):format(zone)) + if not path or path == "" then return false end + + fs.mount(path, self.load_dir) + + local popup = Dialog:simplePopup("Loading zone", "Please wait while loading the zone...") + core.display.forceRedraw() + + local loadedZone = self:loadReal("main") + + -- Delay loaded must run + for i, o in ipairs(self.delayLoad) do +-- print("loader executed for class", o, o.__CLASSNAME) + o:loaded() + end + + game:unregisterDialog(popup) + + fs.umount(path) + return loadedZone +end + --- Loads a level function _M:loadLevel(zone, level) local path = fs.getRealPath(self.save_dir..("level-%s-%d.teal"):format(zone, level)) diff --git a/game/engine/Zone.lua b/game/engine/Zone.lua index b5d8a9bbfccdef5bd6835aeaa0f166854fd30948..f9de14c15f1fc105d099392101e41b92f76f0493 100644 --- a/game/engine/Zone.lua +++ b/game/engine/Zone.lua @@ -25,24 +25,37 @@ end -- @param short_name the short name of the zone to load, if should correspond to a directory in your module data/zones/short_name/ with a zone.lua, npcs.lua, grids.lua and objects.lua files inside function _M:init(short_name) self.short_name = short_name - self:load() - self.level_range = self.level_range or {1,1} - if type(self.level_range) == "number" then self.level_range = {self.level_range, self.level_range} end - self.level_scheme = self.level_scheme or "fixed" - assert(self.max_level, "no zone max level") - self.levels = self.levels or {} - self.npc_list = self.npc_class:loadList("/data/zones/"..self.short_name.."/npcs.lua") - self.grid_list = self.grid_class:loadList("/data/zones/"..self.short_name.."/grids.lua") - self.object_list = self.object_class:loadList("/data/zones/"..self.short_name.."/objects.lua") - self.trap_list = self.trap_class:loadList("/data/zones/"..self.short_name.."/traps.lua") - - -- Determine a zone base level - self.base_level = self.level_range[1] - if self.level_scheme == "player" then - local plev = game:getPlayer().level - self.base_level = util.bound(plev, self.level_range[1], self.level_range[2]) + if not self:load() then + self.level_range = self.level_range or {1,1} + if type(self.level_range) == "number" then self.level_range = {self.level_range, self.level_range} end + self.level_scheme = self.level_scheme or "fixed" + assert(self.max_level, "no zone max level") + self.levels = self.levels or {} + self.npc_list = self.npc_class:loadList("/data/zones/"..self.short_name.."/npcs.lua") + self.grid_list = self.grid_class:loadList("/data/zones/"..self.short_name.."/grids.lua") + self.object_list = self.object_class:loadList("/data/zones/"..self.short_name.."/objects.lua") + self.trap_list = self.trap_class:loadList("/data/zones/"..self.short_name.."/traps.lua") + + -- Determine a zone base level + self.base_level = self.level_range[1] + if self.level_scheme == "player" then + local plev = game:getPlayer().level + self.base_level = util.bound(plev, self.level_range[1], self.level_range[2]) + end + print("Initiated zone", self.name, "with base_level", self.base_level) + else + print("Loaded zone", self.name, "with base_level", self.base_level) + end +end + +--- Leaves a zone +-- Saves the zone to a .teaz file if requested with persistant="zone" flag +function _M:leave() + if type(self.persistant) == "string" and self.persistant == "zone" then + local save = Savefile.new(game.save_name) + save:saveZone(self) + save:close() end - print("Initiated zone", self.name, "with base_level", self.base_level) end --- Parses the npc/objects list and compute rarities for random generation @@ -246,9 +259,16 @@ function _M:addEntity(level, e, typ, x, y) end function _M:load() - local f, err = loadfile("/data/zones/"..self.short_name.."/zone.lua") - if err then error(err) end - local data = f() + -- Try to load from a savefile + local save = Savefile.new(game.save_name) + local data = save:loadZone(self.short_name) + save:close() + + if not data then + local f, err = loadfile("/data/zones/"..self.short_name.."/zone.lua") + if err then error(err) end + data = f() + end for k, e in pairs(data) do self[k] = e end end @@ -273,7 +293,11 @@ function _M:leaveLevel(no_close, lev, old_lev) if not no_close and game.level and game.level.map then game:leaveLevel(game.level, lev, old_lev) - if type(game.level.data.persistant) == "string" and game.level.data.persistant == "memory" then + if type(game.level.data.persistant) == "string" and game.level.data.persistant == "zone" then + print("[LEVEL] persisting to zone memory", game.level.id) + self.memory_levels = self.memory_levels or {} + self.memory_levels[game.level.level] = game.level + elseif type(game.level.data.persistant) == "string" and game.level.data.persistant == "memory" then print("[LEVEL] persisting to memory", game.level.id) game.memory_levels = game.memory_levels or {} game.memory_levels[game.level.id] = game.level @@ -300,7 +324,18 @@ function _M:getLevel(game, lev, old_lev, no_close) local level -- Load persistant level? - if type(level_data.persistant) == "string" and level_data.persistant == "memory" then + if type(level_data.persistant) == "string" and level_data.persistant == "zone" then + self.memory_levels = self.memory_levels or {} + level = self.memory_levels[lev] + + if level then + -- Setup the level in the game + game:setLevel(level) + -- Recreate the map because it could have been saved with a different tileset or whatever + -- This is not needed in case of a direct to file persistance becuase the map IS recreated each time anyway + level.map:recreate() + end + elseif type(level_data.persistant) == "string" and level_data.persistant == "memory" then game.memory_levels = game.memory_levels or {} level = game.memory_levels[self.short_name.."-"..lev] diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 80944b636ac778416d5f0f6d3b7d9cc26716c151..c51778d22fcdc67884109ed8895d05fd89992114 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -195,6 +195,7 @@ function _M:changeLevel(lev, zone) if zone then if self.zone then self.zone:leaveLevel(false, lev, old_lev) + self.zone:leave() end self.zone = Zone.new(zone) end diff --git a/game/modules/tome/data/zones/illusory-castle/zone.lua b/game/modules/tome/data/zones/illusory-castle/zone.lua index 4f1e51161d469d82a5bf2d54c8f4241ea10df1df..9c7cd7011bcaa3142537198538156c7926ed4dd9 100644 --- a/game/modules/tome/data/zones/illusory-castle/zone.lua +++ b/game/modules/tome/data/zones/illusory-castle/zone.lua @@ -7,7 +7,7 @@ return { width = 50, height = 50, all_remembered = true, all_lited = true, --- persistant = true, +-- persistant = "zone", generator = { map = { -- class = "engine.generator.map.Rooms", diff --git a/game/modules/tome/data/zones/maze/zone.lua b/game/modules/tome/data/zones/maze/zone.lua index a2dd3b01ae97d08ec3aedd402f07d6f7fdbad0ce..96ab6478b4c9163bba59d233d0df680c00cac5cf 100644 --- a/game/modules/tome/data/zones/maze/zone.lua +++ b/game/modules/tome/data/zones/maze/zone.lua @@ -7,7 +7,7 @@ return { width = 40, height = 40, -- all_remembered = true, -- all_lited = true, - persistant = true, + persistant = "zone", generator = { map = { class = "engine.generator.map.Maze", diff --git a/game/modules/tome/data/zones/old-forest/zone.lua b/game/modules/tome/data/zones/old-forest/zone.lua index f5649345d6e361ad8ab025d784bb8cbee3e80531..05663c6d6f5ec9bba9899a16afb97a12376881b3 100644 --- a/game/modules/tome/data/zones/old-forest/zone.lua +++ b/game/modules/tome/data/zones/old-forest/zone.lua @@ -7,7 +7,7 @@ return { width = 50, height = 50, -- all_remembered = true, all_lited = true, - persistant = true, + persistant = "zone", generator = { map = { class = "engine.generator.map.Roomer", diff --git a/game/modules/tome/data/zones/sandworm-lair/zone.lua b/game/modules/tome/data/zones/sandworm-lair/zone.lua index 7d653b216d3525ed1edac217e1125ae1a62af340..2dbd19335f6ad409e34338d56e4a79ba20eefcab 100644 --- a/game/modules/tome/data/zones/sandworm-lair/zone.lua +++ b/game/modules/tome/data/zones/sandworm-lair/zone.lua @@ -7,7 +7,7 @@ return { width = 50, height = 50, -- all_remembered = true, -- all_lited = true, - persistant = true, + persistant = "zone", generator = { map = { class = "engine.generator.map.Roomer", diff --git a/game/modules/tome/data/zones/tol-falas/zone.lua b/game/modules/tome/data/zones/tol-falas/zone.lua index ac60d8e621feab923f3d0129cdb2758af019360e..4c89a140e2777df35c63ef9c1fc1e19f0267a1b6 100644 --- a/game/modules/tome/data/zones/tol-falas/zone.lua +++ b/game/modules/tome/data/zones/tol-falas/zone.lua @@ -7,7 +7,7 @@ return { width = 50, height = 50, -- all_remembered = true, -- all_lited = true, - persistant = true, + persistant = "zone", generator = { map = { class = "engine.generator.map.Roomer", diff --git a/game/modules/tome/data/zones/tower-amon-sul/zone.lua b/game/modules/tome/data/zones/tower-amon-sul/zone.lua index b608735ed45b8b4f97e0fa33a2fb72cff3b83bb8..2507490c3e0e1befd2607b6adf7bf4ad7a81d6a0 100644 --- a/game/modules/tome/data/zones/tower-amon-sul/zone.lua +++ b/game/modules/tome/data/zones/tower-amon-sul/zone.lua @@ -7,7 +7,7 @@ return { width = 50, height = 50, -- all_remembered = true, -- all_lited = true, - persistant = true, + persistant = "zone", -- ambiant_music = "10_23.ogg", generator = { map = { diff --git a/game/modules/tome/data/zones/trollshaws/zone.lua b/game/modules/tome/data/zones/trollshaws/zone.lua index c0fa8ac05bd87d608d0f59afff4287f8180d3778..ccceb72085025ba2967ddfeec831abe04bf5abc4 100644 --- a/game/modules/tome/data/zones/trollshaws/zone.lua +++ b/game/modules/tome/data/zones/trollshaws/zone.lua @@ -7,7 +7,7 @@ return { width = 50, height = 50, -- all_remembered = true, all_lited = true, - persistant = true, + persistant = "zone", generator = { map = { class = "engine.generator.map.Roomer",