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

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

Patch by Aspidites:

  • Modified settings api slightly to prepare for other changes. Settings.filenames is replaced by Settings.paths as it will be more useful, IMHO.
  • Added copyright notice to settings module
  • Renamed DataDirectory? to SystemDataDirectory? and added UserDataDirectory? to [fife] section of default config file.
  • Implemented proper command line interface for settings.py

+ If multiple system names are given, multiple settings files

are generated, with the system name prepended to the filename

+ Both system and user data directories may be specified

+ It is possible to change the filename
+ not speficying anything will assume the system to be the one that

the script was run on and a filename of system.cfg

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