source: branches/active/character_customization/game/parpg/gamemodel.py @ 794

Revision 794, 31.6 KB checked in by aspidites, 8 years ago (diff)

Patch by Aspidites

  • added "DataDirectory?" option to [fife] section of system.cfg
  • broke down *File options and made additonal *Directory options

where neccessary

  • updated references in source files to comply with these changes
  • Property svn:eol-style set to native
Line 
1#   This file is part of PARPG.
2
3#   PARPG is free software: you can redistribute it and/or modify
4#   it under the terms of the GNU General Public License as published by
5#   the Free Software Foundation, either version 3 of the License, or
6#   (at your option) any later version.
7
8#   PARPG is distributed in the hope that it will be useful,
9#   but WITHOUT ANY WARRANTY; without even the implied warranty of
10#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11#   GNU General Public License for more details.
12
13#   You should have received a copy of the GNU General Public License
14#   along with PARPG.  If not, see <http://www.gnu.org/licenses/>.
15
16# there should be NO references to FIFE here!
17import sys
18import os.path
19import logging
20from copy import deepcopy
21
22from fife import fife
23from fife.extensions.serializers.xmlobject import XMLObjectLoader
24
25from gamestate import GameState
26from objects import createObject
27from objects.composed import CarryableItem, CarryableContainer
28from gamemap import GameMap
29from common.utils import locateFiles
30from common.utils import parseBool
31from inventory import Inventory
32from parpg.dialogueparsers import YamlDialogueParser, DialogueFormatError
33
34try:
35    import xml.etree.cElementTree as ElementTree
36except ImportError:
37    import xml.etree.ElementTree as ElementTree
38
39import yaml
40
41class GameModel(object):
42    """GameModel holds the logic for the game.
43       Since some data (object position and so forth) is held in the
44       fife, and would be pointless to replicate, we hold a instance of
45       the fife view here. This also prevents us from just having a
46       function heavy controller."""
47    ALL_AGENTS_KEY = "All"
48    MAX_ID_NUMBER = 1000
49   
50    def __init__(self, engine, settings):
51        """Initialize the instance.
52        @param engine: A fife.Engine object
53        @type emgome: fife.Engine
54        @param setting: The applications settigns
55        @type setting: parpg.settings.Settings object
56        @return: None"""
57        self.settings = settings
58        data_dir = self.settings.fife.DataDirectory
59
60        self.map_change = False
61        self.load_saver = False
62        self.savegame = None
63        quests_directory = os.path.join(data_dir,
64                                        self.settings.parpg.QuestsDirectory)
65        self.game_state = GameState(quests_dir=quests_directory)
66        #self.game_state.quest_engine =
67        #self.game_state.quest_engine.readQuests()
68        self.pc_run = 1
69        self.target_position = None
70        self.target_map_name = None
71        self.object_db = {}
72        self.active_map = None
73        self.map_files = {}
74        self.agents = {}
75        self.agents[self.ALL_AGENTS_KEY] = {}
76        self.engine = engine
77        self.fife_model = engine.getModel()
78
79        # set values from settings
80        maps_file = os.path.join(data_dir, self.settings.parpg.MapsDirectory,
81                                 self.settings.parpg.MapsFile)
82        self.game_state.maps_file = maps_file
83        all_agents_file = os.path.join(data_dir, 
84                                       self.settings.parpg.MapsDirectory,
85                                       self.settings.parpg.AllAgentsFile)
86        self.all_agents_file = all_agents_file
87        objects_dir = os.path.join(data_dir,
88                                    self.settings.parpg.ObjectsDirectory)
89        self.objects_directory = objects_dir
90        object_db_file = os.path.join(self.objects_directory,
91                                      self.settings.parpg.ObjectDatabaseFile)
92        self.object_db_file = object_db_file
93        dialogues_dir = os.path.join(data_dir, 
94                                     self.settings.parpg.DialoguesDirectory)
95        self.dialogues_directory = dialogues_dir
96        self.dialogues = {}
97        self.agent_import_files = {}
98        self.obj_loader = XMLObjectLoader(
99                                          self.engine.getImagePool(), 
100                                          self.engine.getAnimationPool(), 
101                                          self.engine.getModel(),
102                                          self.engine.getVFS() 
103                                          )
104
105    def checkAttributes(self, attributes):
106        """Checks for attributes that where not given in the map file
107        and fills them with values from the object database
108        @param attributes: attributes to check
109        @type attributes: Dictionary
110        @return: The modified attributes""" 
111        if attributes.has_key("object_type"):
112            class_name = attributes.pop("object_type")
113        else:
114            class_name = attributes["type"]
115        if not attributes.has_key("type"):
116            attributes["type"] = class_name
117        if self.object_db.has_key(class_name):
118            db_attributes = deepcopy(self.object_db[class_name])
119            for key in db_attributes.keys():
120                if attributes.has_key(key):
121                    attributes[key] = attributes[key] or db_attributes[key]
122                else:
123                    attributes[key] = db_attributes[key]
124        return attributes
125   
126    def isIDUsed(self, ID):
127        if self.game_state.hasObject(ID):
128            return True
129        for namespace in self.agents:
130            if ID in self.agents[namespace]:
131                return True
132        return False
133   
134    def createUniqueID(self, ID):
135        if self.isIDUsed(ID):
136            id_number = 1
137            while self.isIDUsed(ID + "_" + str(id_number)):
138                id_number += 1
139                if id_number > self.MAX_ID_NUMBER:
140                    raise ValueError(
141                        "Number exceeds MAX_ID_NUMBER:" + str(self.MAX_ID_NUMBER))
142           
143            ID = ID + "_" + str(id_number)
144        return ID
145
146    def createContainerItems(self, container_objs):
147        """Create the items of a container from a dictionary
148        @param container_objs: Dictionary containing the items
149        @type container_objs: dict"""
150        items = []
151        for container_obj in container_objs:
152            items.append(self.createContainerObject(container_obj))
153       
154        return items
155
156    def createContainerObject(self, attributes):
157        """Create an object that can be stored in
158        an container and return it
159        @param attributes: Dictionary of all object attributes
160        @type attributes: Dictionary
161        @return: The created object """
162        # create the extra data
163        extra = {}
164        extra['controller'] = self
165        attributes = self.checkAttributes(attributes)
166       
167        info = {}
168        info.update(attributes)
169        info.update(extra)
170        ID = info.pop("id") if info.has_key("id") else info.pop("ID")
171        if not info.has_key("item_type"):
172            info["item_type"] = info["type"]
173        ID = self.createUniqueID(ID)
174        if info.has_key("attributes"):
175            attributes = info["attributes"]
176            if "Container" in attributes:
177                info["actions"]["Open"] = ""
178                if info.has_key("Items"):
179                    inventory_objs = info["Items"]
180                    info["items"] = self.createContainerItems(inventory_objs)
181               
182                new_item = CarryableContainer(ID = ID, **info) 
183            else:
184                new_item = CarryableItem(ID = ID, **info) 
185        else:
186            new_item = CarryableItem(ID = ID, **info) 
187        self.game_state.addObject(None, new_item)
188        return new_item
189     
190    def createInventoryObject(self, container, attributes):
191        """Create an inventory object and place it into a container
192           @type container: base.Container
193           @param container: Container where the item is on
194           @type attributes: Dictionary
195           @param attributes: Dictionary of all object attributes
196           @return: None"""
197        index = attributes.pop("index") if attributes.has_key("index") else None
198        slot = attributes.pop("slot") if attributes.has_key("slot") else None
199        obj = self.createContainerObject(attributes)       
200        #obj = createObject(attributes, extra)
201        if slot:
202            container.moveItemToSlot(obj, slot)
203        else:
204            container.placeItem(obj, index)
205   
206    def deleteObject(self, object_id):
207        """Removes an object from the game
208        @param object_id: ID of the object
209        @type object_id: str """
210        del self.agents["All"][object_id]
211        self.game_state.deleteObject(object_id)
212       
213    def save(self, path, filename):
214        """Writes the saver to a file.
215           @type filename: string
216           @param filename: the name of the file to write to
217           @return: None"""
218        fname = '/'.join([path, filename])
219        try:
220            save_file = open(fname, 'w')
221        except(IOError):
222            sys.stderr.write("Error: Can't create save game: " + fname + "\n")
223            return
224        save_state = {}
225        save_state["Agents"] = {}
226        for map_name in self.agents:
227            if map_name == self.ALL_AGENTS_KEY:
228                continue
229            agents_dict = {}
230            for agent in self.agents[map_name]:
231                agent_obj = self.game_state.getObjectById(agent, map_name)
232                agent_inst = self.game_state.maps[map_name].\
233                                    agent_layer.getInstance(agent)
234                agent_dict = self.agents[map_name][agent]
235                agent_dict.update(agent_obj.getStateForSaving())
236                agent_dict["Rotation"] = agent_inst.getRotation()
237                agents_dict[agent] = agent_dict
238            save_state["Agents"][map_name] = agents_dict
239        agents_dict = {}
240        for agent in self.agents["All"]:
241            map_name = self.agents["All"][agent]["Map"]
242            agent_dict = self.agents["All"][agent]
243            agent_obj = None
244            if agent == "PlayerCharacter":
245                agent_obj = self.game_state.player_character
246            else:
247                agent_obj = self.game_state.getObjectById(agent, map_name)
248            if agent_obj:
249                agent_inst = self.game_state.maps[map_name].\
250                                    agent_layer.getInstance(agent)
251                agent_dict.update(agent_obj.getStateForSaving())
252                agent_dict["Rotation"] = agent_inst.getRotation()
253                agent_dict["MapName"] = map_name
254            agents_dict[agent] = agent_dict
255        save_state["Agents"]["All"] = agents_dict
256        save_state["GameState"] = self.game_state.getStateForSaving()
257        yaml.dump(save_state, save_file)
258       
259        save_file.close()       
260
261    def load(self, path, filename):
262        """Loads a saver from a file.
263           @type filename: string
264           @param filename: the name of the file (including path) to load from
265           @return: None"""
266        fname = '/'.join([path, filename])
267
268        try:
269            load_file = open(fname, 'r')
270        except(IOError):
271            sys.stderr.write("Error: Can't find save game file\n")
272            return       
273        self.deleteMaps()
274        self.clearAgents()
275       
276        save_state = yaml.load(load_file)
277        self.game_state.restoreFromState(save_state["GameState"])
278        maps = save_state["Agents"]
279        for map_name in maps:
280            for agent_name in maps[map_name]:
281                agent = {agent_name:maps[map_name][agent_name]}
282                self.addAgent(map_name, agent)
283               
284        # Load the current map
285        if self.game_state.current_map_name:
286            self.loadMap(self.game_state.current_map_name)         
287        load_file.close()
288       
289
290        # Recreate all the behaviours. These can't be saved because FIFE
291        # objects cannot be pickled
292       
293        self.placeAgents()
294        self.placePC()
295     
296        # In most maps we'll create the PlayerCharacter Instance internally.
297        # In these cases we need a target position
298         
299    def teleport(self, agent, position):
300        """Called when a an agent is moved instantly to a new position.
301        The setting of position may wan to be created as its own method down the road.
302        @type position: String Tuple
303        @param position: X,Y coordinates passed from engine.changeMap
304        @return: fife.Location"""
305        print position
306        coord = fife.DoublePoint3D(float(position[0]), float(position[1]), 0)
307        location = fife.Location(self.active_map.agent_layer)
308        location.setMapCoordinates(coord)
309        agent.teleport(location)         
310               
311    def getObjectAtCoords(self, coords):
312        """Get the object which is at the given coords
313        @type coords: fife.Screenpoint
314        @param coords: Coordinates where to check for an object
315        @rtype: fife.Object
316        @return: An object or None"""
317        instances = self.active_map.cameras[
318                                            self.active_map.my_cam_id].\
319            getMatchingInstances(coords, self.active_map.agent_layer)
320        # no object returns an empty tuple
321        if(instances != ()):
322            front_y = 0
323           
324
325            for obj in instances:
326                # check to see if this in our list at all
327                if(self.objectActive(obj.getId())):
328                    # check if the object is on the foreground
329                    obj_map_coords = \
330                                      obj.getLocation().getMapCoordinates()
331                    obj_screen_coords = self.active_map.\
332                        cameras[self.active_map.my_cam_id]\
333                        .toScreenCoordinates(obj_map_coords)
334
335                    if obj_screen_coords.y > front_y:
336                        #Object on the foreground
337                        front_y = obj_screen_coords.y
338                        return obj
339                    else:
340                        return None
341        else:
342            return None
343
344    def getCoords(self, click):
345        """Get the map location x, y coordinates from the screen coordinates
346           @type click: fife.ScreenPoint
347           @param click: Screen coordinates
348           @rtype: fife.Location
349           @return: The map coordinates"""
350        coord = self.active_map.cameras[self.active_map.my_cam_id].\
351                    toMapCoordinates(click, False)
352        coord.z = 0
353        location = fife.Location(self.active_map.agent_layer)
354        location.setMapCoordinates(coord)
355        return location
356
357    def pause(self, paused):
358        """ Pause/Unpause the game
359        @return: nothing"""
360        if self.active_map:
361            self.active_map.pause(paused)
362   
363    def togglePause(self):
364        """ Toggle paused state.
365        @return: nothing"""
366        self.active_map.togglePause()
367       
368    def isPaused(self):
369        """Returns wheter the game is paused or not"""
370        return self.active_map.isPaused()
371   
372    def readMapFiles(self):
373        """Read all a available map-files and store them"""
374        maps_data = file(self.game_state.maps_file)
375        self.map_files = yaml.load(maps_data)["Maps"]
376   
377    def addAgent(self, namespace, agent):
378        """Adds an agent to the agents dictionary
379        @param namespace: the namespace where the agent is to be added to
380        @type namespace: str
381        @param agent: The agent to be added
382        @type agent: dict """
383        from fife.extensions.serializers.xml_loader_tools import loadImportFile
384        if not self.agents.has_key(namespace):
385            self.agents[namespace] = {}
386           
387        agent_values = agent.values()[0]
388        unique_agent_id = self.createUniqueID(agent.keys()[0])
389        del agent[agent.keys()[0]]
390        agent[unique_agent_id] = agent_values
391        self.agents[namespace].update(agent)
392        object_model = ""
393        if agent_values.has_key("ObjectModel"): 
394            object_model =  agent_values["ObjectModel"]
395        elif agent_values["ObjectType"] == "MapItem":
396            object_data = self.object_db[agent_values["ItemType"]]
397            object_model = object_data["gfx"] if object_data.has_key("gfx") \
398                        else "generic_item"
399        else:
400            object_model = self.object_db[agent_values["ObjectType"]]["gfx"]
401        import_file = self.agent_import_files[object_model]
402        loadImportFile(self.obj_loader, import_file, self.engine)
403       
404    def readAgentsOfMap(self, map_name):
405        """Read the agents of the map
406        @param map_name: Name of the map
407        @type map_name: str """
408        #Get the agents of the map       
409        map_agents_file = self.map_files[map_name].\
410                            replace(".xml", "_agents.yaml")   
411        agents_data = file(map_agents_file)
412        agents = yaml.load_all(agents_data)
413        for agent in agents:
414            if not agent == None:
415                self.addAgent(map_name, agent) 
416   
417    def readAllAgents(self):
418        """Read the agents of the all_agents_file and store them"""
419        agents_data = file(self.all_agents_file)
420        agents = yaml.load_all(agents_data)
421        for agent in agents:
422            if not agent == None:
423                self.addAgent(self.ALL_AGENTS_KEY, agent) 
424               
425    def getAgentsOfMap(self, map_name):
426        """Returns the agents that are on the given map
427        @param map_name: Name of the map
428        @type map_name: str
429        @return: A dictionary with the agents of the map"""
430        if not self.agents.has_key(map_name):
431            return {}
432        ret_dict = self.agents[map_name].copy()
433        for agent_name, agent_value in self.agents[self.ALL_AGENTS_KEY]\
434                                                .iteritems():
435            if agent_value["Map"] == map_name:
436                ret_dict[agent_name] = agent_value
437        return ret_dict
438               
439    def getAgentsOfActiveMap(self):
440        """Returns the agents that are on active map
441        @return: A dictionary with the agents of the map """
442        return self.getAgentsOfMap(self.active_map.map.getId())
443
444    def clearAgents(self):
445        """Resets the agents dictionary"""
446        self.agents = {}
447        self.agents[self.ALL_AGENTS_KEY] = {}
448   
449    def loadMap(self, map_name):
450        """Load a new map.
451           @type map_name: string
452           @param map_name: Name of the map to load
453           @return: None"""
454        if not map_name in self.game_state.maps: 
455            map_file = self.map_files[map_name]
456            new_map = GameMap(self.engine, self)
457            self.game_state.maps[map_name] = new_map
458            new_map.load(map_file)   
459
460    def createAgent(self, agent, inst_id):
461        object_type = agent["ObjectType"]
462        object_id = agent["ObjectModel"] \
463                                if agent.has_key("ObjectModel") \
464                                else None
465        if object_id == None:
466            if object_type == "MapItem":
467                object_data = self.object_db[agent["ItemType"]]
468                object_id = object_data["gfx"] if object_data.has_key("gfx") \
469                            else "generic_item"
470            else:
471                object_id = self.object_db[object_type]["gfx"]
472        map_obj = self.fife_model.getObject(str(object_id), "PARPG")
473        if not map_obj:
474            print ''.join(['Object with inst_id=', str(object_id), 
475                           ' ns=PARPG', \
476                           ' could not be found. Omitting...'])
477
478        x_pos = agent["Position"][0]
479        y_pos = agent["Position"][1]
480        z_pos = agent["Position"][2] if len(agent["Position"]) == 3 \
481                                        else -0.1 if object_type == "MapItem" \
482                                        else 0.0 
483        stack_pos = agent["Stackposition"] if \
484                        agent.has_key("StackPosition") \
485                        else None
486        inst = self.active_map.agent_layer.\
487                        createInstance(map_obj,
488                                       fife.ExactModelCoordinate(x_pos, 
489                                                                 y_pos, 
490                                                                 z_pos),
491                                       inst_id)
492        inst.setId(inst_id)
493
494        rotation = agent["Rotation"]
495        inst.setRotation(rotation)
496
497        fife.InstanceVisual.create(inst)
498        if (stack_pos):
499            inst.get2dGfxVisual().setStackPosition(int(stack_pos))
500
501        if (map_obj.getAction('default')):
502            target = fife.Location(self.active_map.agent_layer)
503            inst.act('default', target, True)
504           
505        inst_dict = {}
506        inst_dict["id"] = inst_id
507        inst_dict["type"] = object_type
508        inst_dict["xpos"] = x_pos
509        inst_dict["ypos"] = y_pos
510        inst_dict["gfx"] = object_id
511        inst_dict["is_open"] = parseBool(agent["Open"]) \
512                                if agent.has_key("Open") \
513                                else False
514        inst_dict["locked"] = parseBool(agent["Locked"]) \
515                                if agent.has_key("Locked") \
516                                else False
517        inst_dict["name"] = agent["ViewName"]
518        inst_dict["real_name"] = agent["RealName"] \
519                                    if agent.has_key("RealName") \
520                                    else agent["ViewName"]
521        inst_dict["text"] = agent["Text"] \
522                                    if agent.has_key("Text") \
523                                    else None
524        if self.dialogues.has_key(inst_id):
525            inst_dict["dialogue"] = self.dialogues[inst_id]
526        inst_dict["target_map_name"] = agent["TargetMap"] \
527                                        if agent.\
528                                            has_key("TargetMap") \
529                                        else None
530        inst_dict["target_x"] = agent["TargetPosition"][0] \
531                                    if agent.\
532                                        has_key("TargetPosition") \
533                                    else None
534        inst_dict["target_y"] = agent["TargetPosition"][1] \
535                                    if agent.\
536                                        has_key("TargetPosition") \
537                                    else None
538        if agent.has_key("Inventory"):
539            inventory = Inventory()
540            inventory_objs = agent["Inventory"]
541            for inventory_obj in inventory_objs:
542                self.createInventoryObject(inventory,
543                                           inventory_obj
544                                           )
545            inst_dict["inventory"] = inventory
546
547        if agent.has_key("Items"):
548            container_objs = agent["Items"]
549            items = self.createContainerItems(container_objs)
550            inst_dict["items"] = items
551           
552        if agent.has_key("ItemType"):
553            if not agent.has_key("item"):
554                item_data = {}
555                item_data["type"] = agent["ItemType"]
556                item_data["ID"] = inst_id
557                item_data = self.createContainerObject(item_data)
558            else:
559                item_data = agent["item"]
560            inst_dict["item"] = item_data
561            inst_dict["item_type"] = agent["ItemType"]
562
563        self.createMapObject(self.active_map.agent_layer, inst_dict)
564   
565    def placeAgents(self):
566        """Places the current maps agents """
567        if not self.active_map:
568            return
569        agents = self.getAgentsOfMap(self.game_state.current_map_name)
570        for agent in agents:
571            if agent == "PlayerCharacter":
572                continue
573            if self.active_map.agent_layer.getInstances(agent):
574                continue
575            self.createAgent(agents[agent], agent)
576
577    def placePC(self):
578        """Places the PlayerCharacter on the map"""
579        agent = self.agents[self.ALL_AGENTS_KEY]["PlayerCharacter"]
580        inst_id = "PlayerCharacter"
581        self.createAgent(agent, inst_id)
582       
583        # create the PlayerCharacter agent
584        self.active_map.addPC()
585        self.game_state.player_character.start()
586        if agent.has_key("PeopleKnown"):
587            self.game_state.player_character.people_i_know = agent["PeopleKnown"]
588                     
589    def changeMap(self, map_name, target_position = None):
590        """Registers for a map change on the next pump().
591           @type map_name: String
592           @param map_name: Id of the map to teleport to
593           @type map_file: String
594           @param map_file: Filename of the map to teleport to
595           @type target_position: Tuple
596           @param target_position: Position of PlayerCharacter on target map.
597           @return None"""
598        # set the parameters for the map change if moving to a new map
599        if map_name != self.game_state.current_map_name:
600            self.target_map_name = map_name
601            self.target_position = target_position
602            # issue the map change
603            self.map_change = True
604
605    def deleteMaps(self):
606        """Clear all currently loaded maps from FIFE as well as clear our
607            local map cache
608            @return: nothing"""
609        self.engine.getModel().deleteMaps()
610        self.engine.getModel().deleteObjects()
611        self.game_state.clearObjects()
612        self.game_state.maps = {}
613       
614    def setActiveMap(self, map_name):
615        """Sets the active map that is to be rendered.
616           @type map_name: String
617           @param map_name: The name of the map to load
618           @return: None"""
619        # Turn off the camera on the old map before we turn on the camera
620        # on the new map.
621        self.active_map.cameras[self.active_map.my_cam_id].setEnabled(False)
622        # Make the new map active.
623        self.active_map = self.game_state.maps[map_name]
624        self.active_map.makeActive()
625        self.game_state.current_map_name = map_name
626
627    def createMapObject (self, layer, attributes):
628        """Create an object and add it to the current map.
629           @type layer: fife.Layer
630           @param layer: FIFE layer object exists in
631           @type attributes: Dictionary
632           @param attributes: Dictionary of all object attributes
633           @type instance: fife.Instance
634           @param instance: FIFE instance corresponding to the object
635           @return: None"""
636        # create the extra data
637        extra = {}
638        if layer is not None:
639            extra['agent_layer'] = layer
640        attributes = self.checkAttributes(attributes)
641       
642        obj = createObject(attributes, extra)
643       
644        if obj.trueAttr("PC"):
645            self.addPC(layer, obj)
646        else:
647            self.addObject(layer, obj) 
648
649    def addPC(self, layer, player_char):
650        """Add the PlayerCharacter to the map
651           @type layer: fife.Layer
652           @param layer: FIFE layer object exists in
653           @type player_char: PlayerCharacter
654           @param player_char: PlayerCharacter object
655           @type instance: fife.Instance
656           @param instance: FIFE instance of PlayerCharacter
657           @return: None"""
658        # For now we copy the PlayerCharacter,
659        # in the future we will need to copy
660        # PlayerCharacter specifics between the different PlayerCharacter's
661        self.game_state.player_character = player_char
662        self.game_state.player_character.setup()       
663        self.game_state.player_character.behaviour.speed = self.settings.parpg.PCSpeed
664
665
666    def addObject(self, layer, obj):
667        """Adds an object to the map.
668           @type layer: fife.Layer
669           @param layer: FIFE layer object exists in
670           @type obj: GameObject
671           @param obj: corresponding object class
672           @type instance: fife.Instance
673           @param instance: FIFE instance of object
674           @return: None"""
675        ref = self.game_state.getObjectById(obj.ID, \
676                                            self.game_state.current_map_name) 
677        if ref is None:
678            # no, add it to the game state
679            self.game_state.addObject(self.game_state.current_map_name, obj)
680        else:
681            # yes, use the current game state data
682            obj.X = ref.X
683            obj.Y = ref.Y
684            obj.gfx = ref.gfx 
685             
686        if obj.trueAttr("NPC"):
687            # create the agent
688            obj.setup()
689            obj.behaviour.speed = self.settings.parpg.PCSpeed - 1
690            # create the PlayerCharacter agent
691            obj.start()
692        if obj.trueAttr("AnimatedContainer"):
693            # create the agent
694            obj.setup()
695
696    def objectActive(self, ident):
697        """Given the objects ID, pass back the object if it is active,
698           False if it doesn't exist or not displayed
699           @type ident: string
700           @param ident: ID of object
701           @rtype: boolean
702           @return: Status of result (True/False)"""
703        for game_object in \
704           self.game_state.getObjectsFromMap(self.game_state.current_map_name):
705            if (game_object.ID == ident):
706                # we found a match
707                return game_object
708        # no match
709        return False   
710
711    def movePlayer(self, position):
712        """Code called when the player should move to another location
713           @type position: fife.ScreenPoint
714           @param position: Screen position to move to
715           @return: None"""
716        if(self.pc_run == 1):
717            self.game_state.player_character.run(position)
718        else:
719            self.game_state.player_character.walk(position)
720       
721    def teleportAgent(self, agent, position):
722        """Code called when an agent should teleport to another location
723           @type position: fife.ScreenPoint
724           @param position: Screen position to teleport to
725           @return: None"""
726        agent.teleport(position)
727        self.agents[agent.ID]["Position"] = position
728
729    def readObjectDB(self):
730        """Reads the Object Information Database from a file. """
731        database_file = file(self.object_db_file, "r")
732        database = yaml.load_all(database_file)
733        for object_info in database:
734            self.object_db.update(object_info)
735
736    def getAgentImportFiles(self):
737        """Searches the agents directory for import files """
738        files = locateFiles("*.xml", self.objects_directory)
739        for xml_file in files:
740            xml_file = os.path.relpath(xml_file).replace("\\", "/")
741            try:
742                root = ElementTree.parse(xml_file).getroot()
743                if root.tag == "object":
744                    self.agent_import_files[root.attrib["id"]] = xml_file
745            except SyntaxError as error:
746                assert(isinstance(error, SyntaxError))
747                print "Error parsing file " + xml_file + ": " + error.msg
748                #TODO: We may want to make this an fatal error later.
749   
750    def getDialogues(self):
751        """Searches the dialogue directory for dialogues """
752        files = locateFiles("*.yaml", self.dialogues_directory)
753        dialogue_parser = YamlDialogueParser()
754        for dialogue_filepath in files:
755            dialogue_filepath = os.path.relpath(dialogue_filepath) \
756                                .replace("\\", "/")
757            # Note Technomage 2010-11-13: the new DialogueEngine uses its own
758            #     parser now, YamlDialogueParser.
759#            dialogues = yaml.load_all(file(dialogue_file, "r"))
760            with file(dialogue_filepath, 'r') as dialogue_file:
761                try:
762                    dialogue = dialogue_parser.load(dialogue_file)
763                except (DialogueFormatError,) as error:
764                    logging.error('unable to load dialogue file {0}: {1}'
765                                  .format(dialogue_filepath, error))
766                else:
767                    self.dialogues[dialogue.npc_name] = dialogue
768            # Note Technomage 2010-11-13: the below code is used to load
769            #     multiple dialogues from a single file. Is this functionality
770            #     used/necessary?
771#            for dialogue in dialogues:
772#                self.dialogues[dialogue["NPC"]] = dialogue
Note: See TracBrowser for help on using the repository browser.