comparison gamemodel.py @ 2:06145a6ee387

Fixed resource path dependencies issue that caused PARPG to crash on start. * PARPG should now run without issue (system installation not tested). * Utilized FIFE's VFS module to remove path dependencies from most PARPG modules. * The new parpg.vfs module is a singleton with a single global variable, VFS, which is a reference to the global VFS instance. Although a singleton is not ideal it should be replaced once PARPG's core code is refactored. * The parpg.vfs singleton is initialized in the parpg.applicaiton.PARPGApplication class with the absolute path to the data directory via the parpg.settings module and corresponding configuration file. * A new DataPath entry was added to the default system configuration file template under the [parpg] section to support the new parpg.vfs module. * Updated the parpg-assets subrepo to revision 3 to fix some dialog file format issues (for details see commit message for parpg-assets). * Fixed a few bugs in the parpg.dialogueparsers.YAMLDialogueParser class related to exception handling.
author M. George Hansen <technopolitica@gmail.com>
date Mon, 06 Jun 2011 15:56:14 -1000
parents 7a89ea5404b1
children 3011bc71ab20
comparison
equal deleted inserted replaced
1:4912a6f97c52 2:06145a6ee387
20 from copy import deepcopy 20 from copy import deepcopy
21 21
22 from fife import fife 22 from fife import fife
23 from fife.extensions.serializers.xmlobject import XMLObjectLoader 23 from fife.extensions.serializers.xmlobject import XMLObjectLoader
24 24
25 from parpg import vfs
25 from gamestate import GameState 26 from gamestate import GameState
26 from objects import createObject 27 from objects import createObject
27 from objects.composed import CarryableItem, CarryableContainer 28 from objects.composed import CarryableItem, CarryableContainer
28 from gamemap import GameMap 29 from gamemap import GameMap
29 from common.utils import locateFiles 30 from common.utils import locateFiles
59 self.settings = settings 60 self.settings = settings
60 61
61 self.map_change = False 62 self.map_change = False
62 self.load_saver = False 63 self.load_saver = False
63 self.savegame = None 64 self.savegame = None
64 quests_directory = os.path.join(self.settings.system_path, 65 quests_directory = settings.parpg.QuestsPath
65 self.settings.parpg.QuestsPath)
66 self.game_state = GameState(quests_dir=quests_directory) 66 self.game_state = GameState(quests_dir=quests_directory)
67 #self.game_state.quest_engine = 67 #self.game_state.quest_engine =
68 #self.game_state.quest_engine.readQuests() 68 #self.game_state.quest_engine.readQuests()
69 self.pc_run = 1 69 self.pc_run = 1
70 self.target_position = None 70 self.target_position = None
76 self.agents[self.ALL_AGENTS_KEY] = {} 76 self.agents[self.ALL_AGENTS_KEY] = {}
77 self.engine = engine 77 self.engine = engine
78 self.fife_model = engine.getModel() 78 self.fife_model = engine.getModel()
79 79
80 # set values from settings 80 # set values from settings
81 maps_file = os.path.join(self.settings.system_path, 81 maps_directory = settings.parpg.MapsPath
82 self.settings.parpg.MapsPath, 82 self.game_state.maps_file = '/'.join([maps_directory,
83 self.settings.parpg.MapsFile) 83 settings.parpg.MapsFile])
84 self.game_state.maps_file = maps_file 84 self.all_agents_file = '/'.join([maps_directory,
85 all_agents_file = os.path.join(self.settings.system_path, 85 settings.parpg.AllAgentsFile])
86 self.settings.parpg.MapsPath, 86 objects_directory = self.settings.parpg.ObjectsPath
87 self.settings.parpg.AllAgentsFile) 87 self.objects_directory = objects_directory
88 self.all_agents_file = all_agents_file 88 self.object_db_file = '/'.join([objects_directory,
89 objects_dir = os.path.join(self.settings.system_path, 89 settings.parpg.ObjectDatabaseFile])
90 self.settings.parpg.ObjectsPath) 90 self.dialogue_directory = settings.parpg.DialoguesPath
91 self.objects_directory = objects_dir
92 object_db_file = os.path.join(self.objects_directory,
93 self.settings.parpg.ObjectDatabaseFile)
94 self.object_db_file = object_db_file
95 dialogues_dir = os.path.join(self.settings.system_path,
96 self.settings.parpg.DialoguesPath)
97 self.dialogues_directory = dialogues_dir
98 self.dialogues = {} 91 self.dialogues = {}
99 self.agent_import_files = {} 92 self.agent_import_files = {}
100 self.obj_loader = XMLObjectLoader( 93 self.obj_loader = XMLObjectLoader(
101 self.engine.getImagePool(), 94 self.engine.getImagePool(),
102 self.engine.getAnimationPool(), 95 self.engine.getAnimationPool(),
371 """Returns wheter the game is paused or not""" 364 """Returns wheter the game is paused or not"""
372 return self.active_map.isPaused() 365 return self.active_map.isPaused()
373 366
374 def readMapFiles(self): 367 def readMapFiles(self):
375 """Read all a available map-files and store them""" 368 """Read all a available map-files and store them"""
376 maps_data = file(self.game_state.maps_file) 369 maps_file = vfs.VFS.open(self.game_state.maps_file)
377 self.map_files = yaml.load(maps_data)["Maps"] 370 self.map_files = yaml.load(maps_file)["Maps"]
378 371
379 def addAgent(self, namespace, agent): 372 def addAgent(self, namespace, agent):
380 """Adds an agent to the agents dictionary 373 """Adds an agent to the agents dictionary
381 @param namespace: the namespace where the agent is to be added to 374 @param namespace: the namespace where the agent is to be added to
382 @type namespace: str 375 @type namespace: str
408 @param map_name: Name of the map 401 @param map_name: Name of the map
409 @type map_name: str """ 402 @type map_name: str """
410 #Get the agents of the map 403 #Get the agents of the map
411 map_agents_file = self.map_files[map_name].\ 404 map_agents_file = self.map_files[map_name].\
412 replace(".xml", "_agents.yaml") 405 replace(".xml", "_agents.yaml")
413 agents_data = file(map_agents_file) 406 agents_data = vfs.VFS.open(map_agents_file)
414 agents = yaml.load_all(agents_data) 407 agents = yaml.load_all(agents_data)
415 for agent in agents: 408 for agent in agents:
416 if not agent == None: 409 if not agent == None:
417 self.addAgent(map_name, agent) 410 self.addAgent(map_name, agent)
418 411
419 def readAllAgents(self): 412 def readAllAgents(self):
420 """Read the agents of the all_agents_file and store them""" 413 """Read the agents of the all_agents_file and store them"""
421 agents_data = file(self.all_agents_file) 414 agents_file = vfs.VFS.open(self.all_agents_file)
422 agents = yaml.load_all(agents_data) 415 agents = yaml.load_all(agents_file)
423 for agent in agents: 416 for agent in agents:
424 if not agent == None: 417 if agent is not None:
425 self.addAgent(self.ALL_AGENTS_KEY, agent) 418 self.addAgent(self.ALL_AGENTS_KEY, agent)
426 419
427 def getAgentsOfMap(self, map_name): 420 def getAgentsOfMap(self, map_name):
428 """Returns the agents that are on the given map 421 """Returns the agents that are on the given map
429 @param map_name: Name of the map 422 @param map_name: Name of the map
728 agent.teleport(position) 721 agent.teleport(position)
729 self.agents[agent.ID]["Position"] = position 722 self.agents[agent.ID]["Position"] = position
730 723
731 def readObjectDB(self): 724 def readObjectDB(self):
732 """Reads the Object Information Database from a file. """ 725 """Reads the Object Information Database from a file. """
733 database_file = file(self.object_db_file, "r") 726 database_file = vfs.VFS.open(self.object_db_file)
734 database = yaml.load_all(database_file) 727 database = yaml.load_all(database_file)
735 for object_info in database: 728 for object_info in database:
736 self.object_db.update(object_info) 729 self.object_db.update(object_info)
737 730
738 def getAgentImportFiles(self): 731 def getAgentImportFiles(self):
739 """Searches the agents directory for import files """ 732 """Searches the agents directory for import files """
740 files = locateFiles("*.xml", self.objects_directory) 733 filepaths = locateFiles("*.xml", self.objects_directory)
741 for xml_file in files: 734 for filepath in filepaths:
742 xml_file = os.path.relpath(xml_file).replace("\\", "/")
743 try: 735 try:
736 xml_file = vfs.VFS.open(filepath)
744 root = ElementTree.parse(xml_file).getroot() 737 root = ElementTree.parse(xml_file).getroot()
745 if root.tag == "object": 738 if root.tag == "object":
746 self.agent_import_files[root.attrib["id"]] = xml_file 739 self.agent_import_files[root.attrib["id"]] = filepath
747 except SyntaxError as error: 740 except SyntaxError as error:
748 assert(isinstance(error, SyntaxError)) 741 logging.error("Error parsing file {0}: {1}".format(filepath,
749 logging.critical("Error parsing file {0}: " 742 error))
750 "{1}".format(xml_file, error.msg))
751 sys.exit(1)
752 743
753 def getDialogues(self): 744 def getDialogues(self):
754 """Searches the dialogue directory for dialogues """ 745 """Searches the dialogue directory for dialogues """
755 files = locateFiles("*.yaml", self.dialogues_directory) 746 files = locateFiles("*.yaml", self.dialogue_directory)
756 dialogue_parser = YamlDialogueParser() 747 dialogue_parser = YamlDialogueParser()
757 for dialogue_filepath in files: 748 for dialogue_filepath in files:
758 dialogue_filepath = os.path.relpath(dialogue_filepath) \
759 .replace("\\", "/")
760 # Note Technomage 2010-11-13: the new DialogueEngine uses its own 749 # Note Technomage 2010-11-13: the new DialogueEngine uses its own
761 # parser now, YamlDialogueParser. 750 # parser now, YamlDialogueParser.
762 # dialogues = yaml.load_all(file(dialogue_file, "r")) 751 # dialogues = yaml.load_all(file(dialogue_file, "r"))
763 with file(dialogue_filepath, 'r') as dialogue_file: 752 dialogue_file = vfs.VFS.open(dialogue_filepath)
764 try: 753 try:
765 dialogue = dialogue_parser.load(dialogue_file) 754 dialogue = dialogue_parser.load(dialogue_file)
766 except (DialogueFormatError,) as error: 755 except DialogueFormatError as error:
767 logging.error('unable to load dialogue file {0}: {1}' 756 logging.error('unable to load dialogue file {0}: {1}'
768 .format(dialogue_filepath, error)) 757 .format(dialogue_filepath, error))
769 else: 758 else:
770 self.dialogues[dialogue.npc_name] = dialogue 759 self.dialogues[dialogue.npc_name] = dialogue
771 # Note Technomage 2010-11-13: the below code is used to load 760 # Note Technomage 2010-11-13: the below code is used to load
772 # multiple dialogues from a single file. Is this functionality 761 # multiple dialogues from a single file. Is this functionality
773 # used/necessary? 762 # used/necessary?
774 # for dialogue in dialogues: 763 # for dialogue in dialogues:
775 # self.dialogues[dialogue["NPC"]] = dialogue 764 # self.dialogues[dialogue["NPC"]] = dialogue