Skip to content
Snippets Groups Projects
Commit c3ddeb22 authored by dg's avatar dg
Browse files

Optimzed the savefile code to not save base and computed entities lists as...

Optimzed the savefile code to not save base and computed entities lists as they can be reconstructed from data files, making savefiles quite smaller


git-svn-id: http://svn.net-core.org/repos/t-engine4@3244 51575b47-30f0-44d4-a5cc-537603b46e54
parent 3fd45982
No related branches found
No related tags found
No related merge requests found
......@@ -30,6 +30,7 @@ function _M:init(level, map)
self.e_array = {}
self.entities = {}
self.entities_list = {}
self.perm_entities_list = {}
end
--- Adds an entity to the level
......@@ -95,8 +96,7 @@ end
--- Serialization
function _M:save()
return class.save(self, {
})
return class.save(self, {entities_list=true})
end
function _M:loaded()
-- Loading the game has defined new uids for entities, yet we hard referenced the old ones
......@@ -106,17 +106,22 @@ function _M:loaded()
nes[e.uid] = e
end
self.entities = nes
self.entities_list = {}
end
--- Setup an entity list for the level, this allows the Zone to pick objects/actors/...
function _M:setEntitiesList(type, list)
self.entities_list[type] = list
function _M:setEntitiesList(type, list, permanent)
if permanent then
self.perm_entities_list[type] = list
else
self.entities_list[type] = list
end
print("Stored entities list", type, list)
end
--- Gets an entity list for the level, this allows the Zone to pick objects/actors/...
function _M:getEntitiesList(type)
return self.entities_list[type]
return self.entities_list[type] or self.perm_entities_list[type]
end
--- Removed, so we remove all entities
......
......@@ -260,7 +260,9 @@ function _M:instanciate(mod, name, new_game, no_reboot)
-- Load the savefile if it exists, or create a new one if not (or if requested)
local save = engine.Savefile.new(_G.game.save_name)
if save:check() and not new_game then
_G.game = save:loadGame()
local delay
_G.game, delay = save:loadGame()
delay()
else
save:delete()
end
......
......@@ -397,16 +397,18 @@ function _M:loadGame()
local loadedGame = 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()
local delay_fct = function()
for i, o in ipairs(self.delayLoad) do
-- print("loader executed for class", o, o.__CLASSNAME)
o:loaded()
end
end
fs.umount(path)
game:unregisterDialog(popup)
return loadedGame
return loadedGame, delay_fct
end
--- Loads a zone
......
......@@ -28,6 +28,8 @@ local print = function() end
--- Defines a zone: a set of levels, with depth, npcs, objects, level generator, ...
module(..., package.seeall, class.make)
_no_save_fields = {}
--- Setup classes to use for level generation
-- Static method
-- @param t table that contains the name of the classes to use
......@@ -57,12 +59,7 @@ function _M:init(short_name, dynamic)
self.level_scheme = self.level_scheme or "fixed"
assert(self.max_level, "no zone max level")
self.levels = self.levels or {}
if not dynamic then
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")
end
if not dynamic then self:loadBaseLists() end
if self.on_setup then self:on_setup() end
......@@ -84,6 +81,14 @@ function _M:updateBaseLevel()
end
end
--- Loads basic entities lists
function _M:loadBaseLists()
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")
end
--- Leaves a zone
-- Saves the zone to a .teaz file if requested with persistent="zone" flag
function _M:leave()
......@@ -128,13 +133,7 @@ function _M:computeRarities(type, list, level, filter, add_level, rarity_field)
local etype = ie
if _G.type(ie) == "number" then etype = "" end
if not level:getEntitiesList(type.."/"..e.egos..":"..etype) then
print("Generating specific ego list", type.."/"..e.egos..":"..etype)
local egos = self:getEgosList(level, type, e.egos, e.__CLASSNAME)
if egos then
local egos_prob = self:computeRarities(type, egos, level, etype ~= "" and function(e) return e[etype] end or nil)
level:setEntitiesList(type.."/"..e.egos..":"..etype, egos_prob)
level:setEntitiesList(type.."/base/"..e.egos..":"..etype, egos)
end
self:generateEgoEntities(level, type, etype, e.egos, e.__CLASSNAME)
end
end
end
......@@ -212,6 +211,18 @@ function _M:pickEntity(list)
return nil
end
--- Compute posible egos for this list
function _M:generateEgoEntities(level, type, etype, e_egos, e___CLASSNAME)
print("Generating specific ego list", type.."/"..e_egos..":"..etype)
local egos = self:getEgosList(level, type, e_egos, e___CLASSNAME)
if egos then
local egos_prob = self:computeRarities(type, egos, level, etype ~= "" and function(e) return e[etype] end or nil)
level:setEntitiesList(type.."/"..e_egos..":"..etype, egos_prob)
level:setEntitiesList(type.."/base/"..e_egos..":"..etype, egos)
return egos
end
end
--- Gets the possible egos
function _M:getEgosList(level, type, group, class)
-- Already loaded ? use it
......@@ -225,6 +236,13 @@ function _M:getEgosList(level, type, group, class)
return list
end
function _M:getEntities(level, type)
local list = level:getEntitiesList(type)
if not list then
end
return list
end
--- Picks and resolve an entity
-- @param level a Level object to generate for
-- @param type one of "object" "terrain" "actor" "trap"
......@@ -243,7 +261,7 @@ function _M:makeEntity(level, type, filter, force_level, prob_filter)
local e
-- No probability list, use the default one and apply filter
if not prob_filter then
local list = level:getEntitiesList(type)
local list = self:getEntities(level, type)
local tries = filter and filter.nb_tries or 500
-- CRUDE ! Brute force ! Make me smarter !
while tries > 0 do
......@@ -258,14 +276,14 @@ function _M:makeEntity(level, type, filter, force_level, prob_filter)
if type == "actor" then base_list = self.npc_list
elseif type == "object" then base_list = self.object_list
elseif type == "trap" then base_list = self.trap_list
else base_list = level:getEntitiesList(type) if not base_list then return nil end end
else base_list = self:getEntities(level, type) if not base_list then return nil end end
local list = self:computeRarities(type, base_list, level, function(e) return self:checkFilter(e, filter, type) end, filter.add_levels, filter.special_rarity)
e = self:pickEntity(list)
print("[MAKE ENTITY] prob list generation", e and e.name, "from list size", #list)
if not e then return nil end
-- No filter
else
local list = level:getEntitiesList(type)
local list = self:getEntities(level, type)
local tries = filter and filter.nb_tries or 50 -- A little crude here too but we only check 50 times, this is simply to prevent duplicate uniques
while tries > 0 do
e = self:pickEntity(list)
......@@ -315,6 +333,7 @@ local pick_ego = function(self, level, e, egos_list, type, picked_etype, etype,
picked_etype[etype] = true
if _G.type(etype) == "number" then etype = "" end
local egos = level:getEntitiesList(type.."/"..e.egos..":"..etype)
if not egos then egos = self:generateEgoEntities(level, type, etype, e.egos, e.__CLASSNAME) end
-- Filter the egos if needed
if ego_filter then
......@@ -478,19 +497,25 @@ function _M:addEntity(level, e, typ, x, y, no_added)
e:check("on_added", level, x, y)
end
--- If we are loaded we need a new uid
function _M:loaded()
if self.reload_lists then self:loadBaseLists() end
end
function _M:load(dynamic)
local ret = true
-- Try to load from a savefile
local data = savefile_pipe:doLoad(game.save_name, "zone", nil, self.short_name)
-- local save = Savefile.new(game.save_name)
-- local data = save:loadZone(self.short_name)
-- save:close()
if not data and not dynamic then
local f, err = loadfile("/data/zones/"..self.short_name.."/zone.lua")
if err then error(err) end
data = f()
ret = false
if type(data.reload_lists) ~= "boolean" or data.reload_lists then
self._no_save_fields = {npc_list=true,grid_list=true,object_list=true,trap_list=true}
end
elseif not data and dynamic then
data = dynamic
ret = false
......@@ -505,9 +530,9 @@ local recurs = function(t)
return nt
end
function _M:getLevelData(lev)
local res = table.clone(self, true)
local res = table.clone(self, true, self._no_save_fields)
if self.levels[lev] then
table.merge(res, self.levels[lev], true)
table.merge(res, self.levels[lev], true, self._no_save_fields)
end
-- Make sure it is not considered a class
res.__CLASSNAME = nil
......
......@@ -62,12 +62,12 @@ function _M:loadMap(file)
end,
prepareEntitiesList = function(type, class, file)
local list = require(class):loadList(file)
self.level:setEntitiesList(type, list)
self.level:setEntitiesList(type, list, true)
end,
prepareEntitiesRaritiesList = function(type, class, file)
local list = require(class):loadList(file)
list = game.zone:computeRarities(type, list, game.level, nil)
self.level:setEntitiesList(type, list)
self.level:setEntitiesList(type, list, true)
end,
setStatusAll = function(s) self.status_all = s end,
addData = function(t)
......
......@@ -37,27 +37,33 @@ function table.print(src, offset)
end
end
function table.clone(tbl, deep)
function table.clone(tbl, deep, k_filter)
local n = {}
k_filter = k_filter or {}
for k, e in pairs(tbl) do
-- Deep copy subtables, but not objects!
if deep and type(e) == "table" and not e.__CLASSNAME then
n[k] = table.clone(e, true)
else
n[k] = e
if not k_filter[k] then
-- Deep copy subtables, but not objects!
if deep and type(e) == "table" and not e.__CLASSNAME then
n[k] = table.clone(e, true, k_filter)
else
n[k] = e
end
end
end
return n
end
function table.merge(dst, src, deep)
function table.merge(dst, src, deep, k_filter)
k_filter = k_filter or {}
for k, e in pairs(src) do
if deep and dst[k] and type(e) == "table" and type(dst[k]) == "table" and not e.__CLASSNAME then
table.merge(dst[k], e, true)
elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then
dst[k] = table.clone(e, true)
else
dst[k] = e
if not k_filter[k] then
if deep and dst[k] and type(e) == "table" and type(dst[k]) == "table" and not e.__CLASSNAME then
table.merge(dst[k], e, true, k_filter)
elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then
dst[k] = table.clone(e, true, k_filter)
else
dst[k] = e
end
end
end
end
......
......@@ -23,7 +23,7 @@ short_name = "gruesome"
author = { "Darren Grey", "darrenjohngrey@hotmail.com" }
homepage = "http://gruesomegames.com/"
version = {1,0,0}
engine = {0,9,21,"te4"}
engine = {0,9,25,"te4"}
description = [[
"It is pitch black. You are likely to eat someone..."
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment