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

Revision 757, 30.9 KB checked in by aspidites, 9 years ago (diff)

Patch by Aspidites:

+ fixed walk speed regression, though in the future, it may be more elegant

to pass the model's settings instance to a PlayableCharacter? constructor

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