source: trunk/game/scripts/gamemodel.py @ 683

Revision 669, 30.6 KB checked in by technomage, 9 years ago (diff)

Patch by Technomage

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