changeset 131:0ffebdca7ba3

Fixed Saving and Loading.
author KarstenBock@gmx.net
date Thu, 29 Sep 2011 18:09:56 +0200
parents 9fcff924eb6f
children ccf4d6cffcf1
files src/parpg/gamemodel.py src/parpg/gamescenecontroller.py src/parpg/gamestate.py src/parpg/objects/action.py
diffstat 4 files changed, 39 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/src/parpg/gamemodel.py	Wed Sep 28 15:01:04 2011 +0200
+++ b/src/parpg/gamemodel.py	Thu Sep 29 18:09:56 2011 +0200
@@ -144,8 +144,7 @@
         @type object_id: str 
         @param new_map: ID of the new map, or None
         @type object_id: str """
-        game_object = self.game_state.getObjectById(object_id)
-        self.deleteObject(object_id)
+        game_object = self.deleteObject(object_id)
         self.game_state.addObject(object_id, new_map, game_object)
     
     def deleteObject(self, object_id):
@@ -153,7 +152,7 @@
         @param object_id: ID of the object
         @type object_id: str """
         del self.agents["All"][object_id]
-        self.game_state.deleteObject(object_id)
+        return self.game_state.deleteObject(object_id)
         
     def save(self, path, filename):
         """Writes the saver to a file.
@@ -166,39 +165,12 @@
         except(IOError):
             sys.stderr.write("Error: Can't create save game: " + fname + "\n")
             return
+
         save_state = {}
-        save_state["Agents"] = {}
-        for map_name in self.agents:
-            if map_name == self.ALL_AGENTS_KEY:
-                continue
-            agents_dict = {}
-            for agent in self.agents[map_name]:
-                agent_obj = self.game_state.getObjectById(agent, map_name)
-                agent_inst = self.game_state.maps[map_name].\
-                                    agent_layer.getInstance(agent)
-                agent_dict = self.agents[map_name][agent]
-                agent_dict.update(agent_obj.getStateForSaving())
-                agent_dict["Rotation"] = agent_inst.getRotation()
-                agents_dict[agent] = agent_dict
-            save_state["Agents"][map_name] = agents_dict
-        agents_dict = {}
-        for agent in self.agents["All"]:
-            map_name = self.agents["All"][agent]["Map"]
-            agent_dict = self.agents["All"][agent]
-            agent_obj = None
-            if agent == "PlayerCharacter":
-                agent_obj = self.game_state.getObjectById("PlayerCharacter").fifeagent
-            else:
-                agent_obj = self.game_state.getObjectById(agent, map_name)
-            if agent_obj:
-                agent_inst = self.game_state.maps[map_name].\
-                                    agent_layer.getInstance(agent)
-                agent_dict.update(agent_obj.getStateForSaving())
-                agent_dict["Rotation"] = agent_inst.getRotation()
-                agent_dict["MapName"] = map_name
-            agents_dict[agent] = agent_dict
-        save_state["Agents"]["All"] = agents_dict
+        save_state["Agents"] = self.agents
+        save_state["Items"] = self.items
         save_state["GameState"] = self.game_state.getStateForSaving()
+        
         yaml.dump(save_state, save_file)
         
         save_file.close()       
@@ -225,21 +197,9 @@
             for agent_name in maps[map_name]:
                 agent = {agent_name:maps[map_name][agent_name]}
                 self.addAgent(map_name, agent)
-                
-        # Load the current map
-        if self.game_state.current_map_name:
-            self.loadMap(self.game_state.current_map_name)         
-        load_file.close()
-        
-
-        # Recreate all the behaviours. These can't be saved because FIFE
-        # objects cannot be pickled
-        
-        self.placeAgents()
-        self.placePC()
+        self.items = save_state["Items"]               
       
-        # In most maps we'll create the PlayerCharacter Instance internally. 
-        # In these cases we need a target position
+        load_file.close()             
          
     def teleport(self, agent, position):
         """Called when a an agent is moved instantly to a new position. 
--- a/src/parpg/gamescenecontroller.py	Wed Sep 28 15:01:04 2011 +0200
+++ b/src/parpg/gamescenecontroller.py	Thu Sep 29 18:09:56 2011 +0200
@@ -336,14 +336,19 @@
                 pc_agent = self.model.agents\
                     [self.model.ALL_AGENTS_KEY]["PlayerCharacter"]
                 pc_agent["Map"] = self.model.target_map_name 
-                pc_agent["Position"] = self.model.target_position
+                pc_agent["Position"] = (self.model.target_position or 
+                                        pc_agent["Position"])
                 player_agent = self.model.active_map.\
                                     agent_layer.getInstance("PlayerCharacter")
-                self.model.game_state.deleteObject("PlayerCharacter")
-                self.model.game_state.deleteObjectsFromMap(
+                self.model.game_state.deleteObject("PlayerCharacter").delete()
+                deleted = self.model.game_state.deleteObjectsFromMap(
                     self.model.game_state.current_map_name
                 )
-                self.model.game_state.deleteObjectsFromMap(None)
+                deleted.extend(
+                    self.model.game_state.deleteObjectsFromMap(None)
+                )
+                for obj in deleted:
+                    obj.delete()
             
             self.model.loadMap(self.model.target_map_name)
             
@@ -481,24 +486,32 @@
         return actions
     
     def saveGame(self, *args, **kwargs):
-        """Saves the game state, delegates call to engine.Engine
+        """Saves the game state, delegates call to gamemodel.GameModel
            @return: None"""
         self.model.pause(False)
         self.pause(False)
         self.view.hud.enabled = True
+        self.model.updateObjectDB(self)
         self.model.save(*args, **kwargs)
 
     def loadGame(self, *args, **kwargs):
-        """Loads the game state, delegates call to engine.Engine
+        """Loads the game state, delegates call to gamemodel.GameModel
            @return: None"""
         # Remove all currently loaded maps so we can start fresh
         self.model.pause(False)
         self.pause(False)
         self.view.hud.enabled = True
         self.model.deleteMaps()
+        for entity in self.entities.copy():
+            entity.delete()
         self.view.hud.inventory = None
 
         self.model.load(*args, **kwargs)
+        # Load the current map
+        if self.model.game_state.current_map_name:
+            self.model.loadMap(self.model.game_state.current_map_name)   
+        self.model.placeAgents(self)
+        self.model.placePC(self)
         self.view.hud.initializeInventory()          
 
     def quitGame(self):
--- a/src/parpg/gamestate.py	Wed Sep 28 15:01:04 2011 +0200
+++ b/src/parpg/gamestate.py	Thu Sep 29 18:09:56 2011 +0200
@@ -22,7 +22,6 @@
         self.quest_engine = QuestEngine(quests_dir)
         self.quest_engine.readQuests()
         self.objects = {}
-        self.objects[None] = {}
         self.object_ids = {}
         self.current_map_name = None
         self.maps = {}
@@ -41,6 +40,8 @@
         @type object: GameObject
         """
         if not self.object_ids.has_key(object_id):
+            if not self.objects.has_key(map_id):
+                self.objects[map_id] = {}
             self.objects[map_id][object_id] = game_object
             self.object_ids[object_id] = map_id
     
@@ -48,15 +49,18 @@
         """Removes an object from the dictionaries
         @param object_id: ID of the object
         @type object_id: str
+        @returns The deleted object
         """
         if self.hasObject(object_id):
             map_id = self.getMapOfObject(object_id)
             if map_id:
                 inst = self.maps[map_id].agent_layer.getInstance(object_id)
                 self.maps[map_id].agent_layer.deleteInstance(inst)
-            self.objects[map_id][object_id].delete()
+            obj = self.objects[map_id][object_id]
             del self.objects[map_id][object_id]
             del self.object_ids[object_id]
+            return obj
+        return None
             
             
     def getObjectsFromMap(self, map_id):
@@ -75,9 +79,11 @@
            @type map: String
            @param map: The map name.
            @returns: None"""
+        deleted_objs = []
         if map_id in self.objects:
             for obj in self.objects[map_id].copy():
-                self.deleteObject(obj)
+                deleted_objs.append(self.deleteObject(obj))
+        return deleted_objs
     
     def hasObject(self, object_id):
         """Check if an object with the given id is present 
@@ -126,11 +132,13 @@
         ret_dict = {}
         ret_dict["CurrentMap"] = self.current_map_name
         ret_dict["Quests"] = self.quest_engine.getStateForSaving()
+        ret_dict["NPCsMet"] = self.npcs_met
         return ret_dict
 
     def restoreFromState(self, state):
         """Restores the state"""
         self.current_map_name = state["CurrentMap"]
+        self.npcs_met = state["NPCsMet"]
         self.quest_engine.readQuests()
         self.quest_engine.restoreFromState(state["Quests"])
 
--- a/src/parpg/objects/action.py	Wed Sep 28 15:01:04 2011 +0200
+++ b/src/parpg/objects/action.py	Thu Sep 29 18:09:56 2011 +0200
@@ -382,6 +382,7 @@
         
     def execute(self):
         real_item = self.item.containable
+        self.item.fifeagent = None
         player = self.model.game_state.getObjectById("PlayerCharacter")
         self.model.moveObject(self.item.general.identifier, None)
         container.put_item(player.container, real_item)