# HG changeset patch # User KarstenBock@gmx.net # Date 1316872104 -7200 # Node ID 9b5498e3bda0ab1d89b077ff3f3d706698bf9a69 # Parent a85d58fcd2530127ee3d193c9f8447f752b187c1 Move the identifier field from the FifeAgent component to the new General component. Added General Entity. diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/bGrease/entity.py --- a/src/parpg/bGrease/entity.py Fri Sep 23 15:09:02 2011 +0200 +++ b/src/parpg/bGrease/entity.py Sat Sep 24 15:48:24 2011 +0200 @@ -1,212 +1,212 @@ -############################################################################# -# -# Copyright (c) 2010 by Casey Duncan and contributors -# All Rights Reserved. -# -# This software is subject to the provisions of the MIT License -# A copy of the license should accompany this distribution. -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# -############################################################################# -"""Grease entities are useful as actionable, interactive -game elements that are often visible to the player. - -You might use entities to represent: - -- Characters -- Bullets -- Particles -- Pick-ups -- Space Ships -- Weapons -- Trees -- Planets -- Explosions - -See :ref:`an example entity class in the tutorial `. -""" - -__version__ = '$Id$' - -__all__ = ('Entity', 'EntityComponentAccessor', 'ComponentEntitySet') - - -class EntityMeta(type): - """The entity metaclass enforces fixed slots of `entity_id` and `world` - for all subclasses. This prevents accidental use of other entity instance - attributes, which may not be saved. - - Class attributes are not affected by this restriction, but subclasses - should be careful not to cause name collisions with world components, - which are exposed as entity attributes. Using a naming convention for - class attributes, such as UPPER_CASE_WITH_UNDERSCORES is recommended to - avoid name clashes. - - Note as a result of this, entity subclasses are not allowed to define - `__slots__`, and doing so will cause a `TypeError` to be raised. - """ - - def __new__(cls, name, bases, clsdict): - if '__slots__' in clsdict: - raise TypeError('__slots__ may not be defined in Entity subclasses') - clsdict['__slots__'] = ('world', 'entity_id') - return type.__new__(cls, name, bases, clsdict) - - -class Entity(object): - """Base class for grease entities. - - Entity objects themselves are merely identifiers within a :class:`grease.world.World`. - They also provide a facade for convenient entity-wise access of component - data. However, they do not contain any data themselves other than an - entity id. - - Entities must be instantiated in the context of a world. To instantiate an - entity, you must pass the world as the first argument to the constructor. - Subclasses that implement the :meth:`__init__()` method, must accept the world - as their first argument (after ``self``). Other constructor arguments can be - specified arbitarily by the subclass. - """ - __metaclass__ = EntityMeta - - def __new__(cls, world, *args, **kw): - """Create a new entity and add it to the world""" - entity = object.__new__(cls) - entity.world = world - entity.entity_id = world.new_entity_id() - world.entities.add(entity) - return entity - - def __getattr__(self, name): - """Return an :class:`EntityComponentAccessor` for this entity - for the component named. - - Example:: - - my_entity.movement - """ - component = getattr(self.world.components, name) - return EntityComponentAccessor(component, self) - - def __setattr__(self, name, value): - """Set the entity data in the named component for this entity. - This sets the values of the component fields to the values of - the matching attributes of the value provided. This value must - have attributes for each of the component fields. - - This allows you to easily copy component data from one entity - to another. - - Example:: - - my_entity.position = other_entity.position - """ - if name in self.__class__.__slots__: - super(Entity, self).__setattr__(name, value) - else: - component = getattr(self.world.components, name) - component.set(self, value) - - def __delattr__(self, name): - """Remove this entity and its data from the component. - - Example:: - - del my_entity.renderable - """ - component = getattr(self.world.components, name) - del component[self] - - def __hash__(self): - return self.entity_id - - def __eq__(self, other): - return self.world is other.world and self.entity_id == other.entity_id - - def __repr__(self): - return "<%s id: %s of %s %x>" % ( - self.__class__.__name__, self.entity_id, - self.world.__class__.__name__, id(self.world)) - - def delete(self): - """Delete the entity from its world. This removes all of its - component data. If then entity has already been deleted, - this call does nothing. - """ - self.world.entities.discard(self) - - @property - def exists(self): - """True if the entity still exists in the world""" - return self in self.world.entities - - -class EntityComponentAccessor(object): - """A facade for accessing specific component data for a single entity. - The implementation is lazy and does not actually access the component - data until needed. If an attribute is set for a component that the - entity is not yet a member of, it is automatically added to the - component first. - - :param component: The :class:`grease.Component` being accessed - :param entity: The :class:`Entity` being accessed - """ - - # beware, name mangling ahead. We want to avoid clashing with any - # user-configured component field names - __data = None - - def __init__(self, component, entity): - clsname = self.__class__.__name__ - self.__dict__['_%s__component' % clsname] = component - self.__dict__['_%s__entity' % clsname] = entity - - def __nonzero__(self): - """The accessor is True if the entity is in the component, - False if not, for convenient membership tests - """ - return self.__entity in self.__component - - def __getattr__(self, name): - """Return the data for the specified field of the entity's component""" - if self.__data is None: - try: - data = self.__component[self.__entity] - except KeyError: - raise AttributeError(name) - clsname = self.__class__.__name__ - self.__dict__['_%s__data' % clsname] = data - return getattr(self.__data, name) - - def __setattr__(self, name, value): - """Set the data for the specified field of the entity's component""" - if self.__data is None: - clsname = self.__class__.__name__ - if self.__entity in self.__component: - self.__dict__['_%s__data' % clsname] = self.__component[self.__entity] - else: - self.__dict__['_%s__data' % clsname] = self.__component.set(self.__entity) - setattr(self.__data, name, value) - - -class ComponentEntitySet(set): - """Set of entities in a component, can be queried by component fields""" - - _component = None - - def __init__(self, component, entities=()): - self.__dict__['_component'] = component - super(ComponentEntitySet, self).__init__(entities) - - def __getattr__(self, name): - if self._component is not None and name in self._component.fields: - return self._component.fields[name].accessor(self) - raise AttributeError(name) - - def __setattr__(self, name, value): - if self._component is not None and name in self._component.fields: - self._component.fields[name].accessor(self).__set__(value) - raise AttributeError(name) - +############################################################################# +# +# Copyright (c) 2010 by Casey Duncan and contributors +# All Rights Reserved. +# +# This software is subject to the provisions of the MIT License +# A copy of the license should accompany this distribution. +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# +############################################################################# +"""Grease entities are useful as actionable, interactive +game elements that are often visible to the player. + +You might use entities to represent: + +- Characters +- Bullets +- Particles +- Pick-ups +- Space Ships +- Weapons +- Trees +- Planets +- Explosions + +See :ref:`an example entity class in the tutorial `. +""" + +__version__ = '$Id$' + +__all__ = ('Entity', 'EntityComponentAccessor', 'ComponentEntitySet') + + +class EntityMeta(type): + """The entity metaclass enforces fixed slots of `entity_id` and `world` + for all subclasses. This prevents accidental use of other entity instance + attributes, which may not be saved. + + Class attributes are not affected by this restriction, but subclasses + should be careful not to cause name collisions with world components, + which are exposed as entity attributes. Using a naming convention for + class attributes, such as UPPER_CASE_WITH_UNDERSCORES is recommended to + avoid name clashes. + + Note as a result of this, entity subclasses are not allowed to define + `__slots__`, and doing so will cause a `TypeError` to be raised. + """ + + def __new__(cls, name, bases, clsdict): + if '__slots__' in clsdict: + raise TypeError('__slots__ may not be defined in Entity subclasses') + clsdict['__slots__'] = ('world', 'entity_id') + return type.__new__(cls, name, bases, clsdict) + + +class Entity(object): + """Base class for grease entities. + + Entity objects themselves are merely identifiers within a :class:`grease.world.World`. + They also provide a facade for convenient entity-wise access of component + data. However, they do not contain any data themselves other than an + entity id. + + Entities must be instantiated in the context of a world. To instantiate an + entity, you must pass the world as the first argument to the constructor. + Subclasses that implement the :meth:`__init__()` method, must accept the world + as their first argument (after ``self``). Other constructor arguments can be + specified arbitarily by the subclass. + """ + __metaclass__ = EntityMeta + + def __new__(cls, world, *args, **kw): + """Create a new entity and add it to the world""" + entity = object.__new__(cls) + entity.world = world + entity.entity_id = world.new_entity_id() + world.entities.add(entity) + return entity + + def __getattr__(self, name): + """Return an :class:`EntityComponentAccessor` for this entity + for the component named. + + Example:: + + my_entity.movement + """ + component = getattr(self.world.components, name) + return EntityComponentAccessor(component, self) + + def __setattr__(self, name, value): + """Set the entity data in the named component for this entity. + This sets the values of the component fields to the values of + the matching attributes of the value provided. This value must + have attributes for each of the component fields. + + This allows you to easily copy component data from one entity + to another. + + Example:: + + my_entity.position = other_entity.position + """ + if name in self.__class__.__slots__: + super(Entity, self).__setattr__(name, value) + else: + component = getattr(self.world.components, name) + component.set(self, value) + + def __delattr__(self, name): + """Remove this entity and its data from the component. + + Example:: + + del my_entity.renderable + """ + component = getattr(self.world.components, name) + del component[self] + + def __hash__(self): + return self.entity_id + + def __eq__(self, other): + return self.world is other.world and self.entity_id == other.entity_id + + def __repr__(self): + return "<%s id: %s of %s %x>" % ( + self.__class__.__name__, self.entity_id, + self.world.__class__.__name__, id(self.world)) + + def delete(self): + """Delete the entity from its world. This removes all of its + component data. If then entity has already been deleted, + this call does nothing. + """ + self.world.entities.discard(self) + + @property + def exists(self): + """True if the entity still exists in the world""" + return self in self.world.entities + + +class EntityComponentAccessor(object): + """A facade for accessing specific component data for a single entity. + The implementation is lazy and does not actually access the component + data until needed. If an attribute is set for a component that the + entity is not yet a member of, it is automatically added to the + component first. + + :param component: The :class:`grease.Component` being accessed + :param entity: The :class:`Entity` being accessed + """ + + # beware, name mangling ahead. We want to avoid clashing with any + # user-configured component field names + __data = None + + def __init__(self, component, entity): + clsname = self.__class__.__name__ + self.__dict__['_%s__component' % clsname] = component + self.__dict__['_%s__entity' % clsname] = entity + + def __nonzero__(self): + """The accessor is True if the entity is in the component, + False if not, for convenient membership tests + """ + return self.__entity in self.__component + + def __getattr__(self, name): + """Return the data for the specified field of the entity's component""" + if self.__data is None: + try: + data = self.__component[self.__entity] + except KeyError: + raise AttributeError(name) + clsname = self.__class__.__name__ + self.__dict__['_%s__data' % clsname] = data + return getattr(self.__data, name) + + def __setattr__(self, name, value): + """Set the data for the specified field of the entity's component""" + if self.__data is None: + clsname = self.__class__.__name__ + if self.__entity in self.__component: + self.__dict__['_%s__data' % clsname] = self.__component[self.__entity] + else: + self.__dict__['_%s__data' % clsname] = self.__component.set(self.__entity) + setattr(self.__data, name, value) + + +class ComponentEntitySet(set): + """Set of entities in a component, can be queried by component fields""" + + _component = None + + def __init__(self, component, entities=()): + self.__dict__['_component'] = component + super(ComponentEntitySet, self).__init__(entities) + + def __getattr__(self, name): + if self._component is not None and name in self._component.fields: + return self._component.fields[name].accessor(self) + raise AttributeError(name) + + def __setattr__(self, name, value): + if self._component is not None and name in self._component.fields: + self._component.fields[name].accessor(self).__set__(value) + raise AttributeError(name) + diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/behaviours/base.py --- a/src/parpg/behaviours/base.py Fri Sep 23 15:09:02 2011 +0200 +++ b/src/parpg/behaviours/base.py Sat Sep 24 15:48:24 2011 +0200 @@ -1,91 +1,91 @@ -# This file is part of PARPG. - -# PARPG is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# PARPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with PARPG. If not, see . - -from fife import fife - -_AGENT_STATE_NONE, _AGENT_STATE_IDLE, _AGENT_STATE_APPROACH, _AGENT_STATE_RUN, _AGENT_STATE_WANDER, _AGENT_STATE_TALK = xrange(6) - -class BaseBehaviour (fife.InstanceActionListener): - """Fife agent listener""" - def __init__(self): - fife.InstanceActionListener.__init__(self) - self.agent = None - self.state = None - - def attachToLayer(self, agent_ID, layer): - """Attaches to a certain layer - @type agent_ID: String - @param agent_ID: ID of the layer to attach to. - @type layer: Fife layer - @param layer: Layer of the agent to attach the behaviour to - @return: None""" - self.agent = layer.getInstance(agent_ID) - self.agent.addActionListener(self) - self.state = _AGENT_STATE_NONE - - def getX(self): - """Get the NPC's x position on the map. - @rtype: integer" - @return: the x coordinate of the NPC's location""" - return self.agent.getLocation().getLayerCoordinates().x - - def getY(self): - """Get the NPC's y position on the map. - @rtype: integer - @return: the y coordinate of the NPC's location""" - return self.agent.getLocation().getLayerCoordinates().y - - def onNewMap(self, layer): - """Sets the agent onto the new layer.""" - if self.agent is not None: - self.agent.removeActionListener(self) - - self.agent = layer.getInstance(self.parent.fifeagent.identifier) - self.agent.addActionListener(self) - self.state = _AGENT_STATE_NONE - - def idle(self): - """@return: None""" - self.state = _AGENT_STATE_IDLE - - def onInstanceActionFinished(self, instance, action): - """@type instance: ??? - @param instance: ??? - @type action: ??? - @param action: ??? - @return: None""" - # First we reset the next behavior - act = self.nextAction - self.nextAction = None - self.idle() - - if act: - act.execute() - - - def getLocation(self): - """Get the agents position as a fife.Location object. - @rtype: fife.Location - @return: the location of the agent""" - return self.agent.getLocation() - - - def talk(self, pc): - """Makes the agent ready to talk to the PC - @return: None""" - self.state = _AGENT_STATE_TALK - self.pc = pc.behaviour.agent - self.idle() +# This file is part of PARPG. + +# PARPG is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# PARPG is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with PARPG. If not, see . + +from fife import fife + +_AGENT_STATE_NONE, _AGENT_STATE_IDLE, _AGENT_STATE_APPROACH, _AGENT_STATE_RUN, _AGENT_STATE_WANDER, _AGENT_STATE_TALK = xrange(6) + +class BaseBehaviour (fife.InstanceActionListener): + """Fife agent listener""" + def __init__(self): + fife.InstanceActionListener.__init__(self) + self.agent = None + self.state = None + + def attachToLayer(self, agent_ID, layer): + """Attaches to a certain layer + @type agent_ID: String + @param agent_ID: ID of the layer to attach to. + @type layer: Fife layer + @param layer: Layer of the agent to attach the behaviour to + @return: None""" + self.agent = layer.getInstance(agent_ID) + self.agent.addActionListener(self) + self.state = _AGENT_STATE_NONE + + def getX(self): + """Get the NPC's x position on the map. + @rtype: integer" + @return: the x coordinate of the NPC's location""" + return self.agent.getLocation().getLayerCoordinates().x + + def getY(self): + """Get the NPC's y position on the map. + @rtype: integer + @return: the y coordinate of the NPC's location""" + return self.agent.getLocation().getLayerCoordinates().y + + def onNewMap(self, layer): + """Sets the agent onto the new layer.""" + if self.agent is not None: + self.agent.removeActionListener(self) + + self.agent = layer.getInstance(self.parent.general.identifier) + self.agent.addActionListener(self) + self.state = _AGENT_STATE_NONE + + def idle(self): + """@return: None""" + self.state = _AGENT_STATE_IDLE + + def onInstanceActionFinished(self, instance, action): + """@type instance: ??? + @param instance: ??? + @type action: ??? + @param action: ??? + @return: None""" + # First we reset the next behavior + act = self.nextAction + self.nextAction = None + self.idle() + + if act: + act.execute() + + + def getLocation(self): + """Get the agents position as a fife.Location object. + @rtype: fife.Location + @return: the location of the agent""" + return self.agent.getLocation() + + + def talk(self, pc): + """Makes the agent ready to talk to the PC + @return: None""" + self.state = _AGENT_STATE_TALK + self.pc = pc.behaviour.agent + self.idle() \ No newline at end of file diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/components/__init__.py --- a/src/parpg/components/__init__.py Fri Sep 23 15:09:02 2011 +0200 +++ b/src/parpg/components/__init__.py Sat Sep 24 15:48:24 2011 +0200 @@ -8,4 +8,5 @@ from usable import Usable from change_map import ChangeMap from equipable import Equipable -from equip import Equip \ No newline at end of file +from equip import Equip +from general import General \ No newline at end of file diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/components/fifeagent.py --- a/src/parpg/components/fifeagent.py Fri Sep 23 15:09:02 2011 +0200 +++ b/src/parpg/components/fifeagent.py Sat Sep 24 15:48:24 2011 +0200 @@ -18,10 +18,10 @@ def __init__(self): """Constructor""" - Component.__init__(self, identifier=str, layer=object, behaviour=object, gfx=str) + Component.__init__(self, layer=object, behaviour=object, gfx=str) def setup_behaviour(agent): """Attach the behaviour to the layer""" if agent.behaviour: - agent.behaviour.attachToLayer(agent.identifier, agent.layer) \ No newline at end of file + agent.behaviour.attachToLayer(agent.entity.getID(), agent.layer) \ No newline at end of file diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/components/general.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parpg/components/general.py Sat Sep 24 15:48:24 2011 +0200 @@ -0,0 +1,21 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from parpg.bGrease.component import Component + +class General(Component): + """Component that stores the general values of an parpg entity""" + + def __init__(self): + """Constructor""" + Component.__init__(self, identifier=str) \ No newline at end of file diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/entities/__init__.py --- a/src/parpg/entities/__init__.py Fri Sep 23 15:09:02 2011 +0200 +++ b/src/parpg/entities/__init__.py Sat Sep 24 15:48:24 2011 +0200 @@ -1,40 +1,40 @@ -# This file is part of PARPG. - -# PARPG is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# PARPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with PARPG. If not, see . - -import sys - -from parpg.bGrease import Entity - -def createEntity(info, world, extra = None): - """Called when we need to get an actual object. - @type info: dict - @param info: stores information about the object we want to create - @type extra: dict - @param extra: stores additionally required attributes - @return: the object""" - # First, we try to get the world, which every game_obj needs. - extra = extra or {} - - # add the extra info - for key, val in extra.items(): - info[key].update(val) - - # this is for testing purposes - new_ent = Entity(world) - for component, data in info.items(): - comp_obj = getattr(new_ent, component) - for key, value in data.items(): - setattr(comp_obj, key, value) - return new_ent +# This file is part of PARPG. + +# PARPG is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# PARPG is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with PARPG. If not, see . + +import sys + +from general import General + +def createEntity(info, identifier, world, extra = None): + """Called when we need to get an actual object. + @type info: dict + @param info: stores information about the object we want to create + @type extra: dict + @param extra: stores additionally required attributes + @return: the object""" + # First, we try to get the world, which every game_obj needs. + extra = extra or {} + + # add the extra info + for key, val in extra.items(): + info[key].update(val) + + # this is for testing purposes + new_ent = General(world, identifier) + for component, data in info.items(): + comp_obj = getattr(new_ent, component) + for key, value in data.items(): + setattr(comp_obj, key, value) + return new_ent diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/entities/general.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parpg/entities/general.py Sat Sep 24 15:48:24 2011 +0200 @@ -0,0 +1,22 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from parpg.bGrease import Entity + +class General(Entity): + + def __init__(self, world, identifier): + self.general.identifier = identifier + + def getID(self): + return self.general.identifier \ No newline at end of file diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/gamemodel.py --- a/src/parpg/gamemodel.py Fri Sep 23 15:09:02 2011 +0200 +++ b/src/parpg/gamemodel.py Sat Sep 24 15:48:24 2011 +0200 @@ -437,7 +437,6 @@ inst.act('default', target, True) - entity_data["fifeagent"]["identifier"] = inst_id if entity_data["fifeagent"].has_key("behaviour"): entity_data["fifeagent"]["behaviour"] = getattr(behaviours, entity_data["fifeagent"]["behaviour"])() else: @@ -446,7 +445,7 @@ entity_data["dialogue"] = {} entity_data["dialogue"]["dialogue"] = self.dialogues[inst_id] - obj = self.createMapObject(self.active_map.agent_layer, entity_data, world) + obj = self.createMapObject(self.active_map.agent_layer, entity_data, inst_id, world) if agent.has_key("Inventory"): inv = agent["Inventory"] @@ -477,9 +476,10 @@ raise Exception("Item %s is not containable or equipable." % item_type) def create_item(self, item_data, world, item_type, data): - item = createEntity(item_data, world, None) + identifier = self.createUniqueID(data["ID"]) + item = createEntity(item_data, identifier, world, None) item.containable.item_type = item_type - self.game_state.addObject(self.createUniqueID(data["ID"]), None, item) + self.game_state.addObject(identifier, None, item) return item def placeAgents(self, world): @@ -544,7 +544,7 @@ self.active_map.makeActive() self.game_state.current_map_name = map_name - def createMapObject (self, layer, attributes, world): + def createMapObject (self, layer, attributes, inst_id, world): """Create an object and add it to the current map. @type layer: fife.Layer @param layer: FIFE layer object exists in @@ -559,7 +559,7 @@ extra['fifeagent'] = {} extra['fifeagent']['layer'] = layer - obj = createEntity(attributes, world, extra) + obj = createEntity(attributes, inst_id, world, extra) if obj: self.addObject(layer, obj) return obj @@ -590,11 +590,11 @@ @type instance: fife.Instance @param instance: FIFE instance of object @return: None""" - ref = self.game_state.getObjectById(obj.fifeagent.identifier, + ref = self.game_state.getObjectById(obj.general.identifier, self.game_state.current_map_name) if ref is None: # no, add it to the game state - self.game_state.addObject(obj.fifeagent.identifier, self.game_state.current_map_name, obj) + self.game_state.addObject(obj.general.identifier, self.game_state.current_map_name, obj) else: # yes, use the current game state data obj.fifeagent.pos.X = ref.X @@ -625,7 +625,7 @@ @return: Status of result (True/False)""" for game_object in \ self.game_state.getObjectsFromMap(self.game_state.current_map_name): - if (game_object.fifeagent.identifier == ident): + if (game_object.general.identifier == ident): # we found a match return game_object # no match diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/gamescenecontroller.py --- a/src/parpg/gamescenecontroller.py Fri Sep 23 15:09:02 2011 +0200 +++ b/src/parpg/gamescenecontroller.py Sat Sep 24 15:48:24 2011 +0200 @@ -409,7 +409,7 @@ # TODO: work more on this when we get NPCData and HeroData straightened # out npc = self.model.game_state.getObjectById( - npc_info.fifeagent.identifier, + npc_info.general.identifier, self.model.game_state.current_map_name ) npc_pos = npc.fifeagent.behaviour.getLocation().getLayerCoordinates() @@ -430,7 +430,7 @@ self.model.game_state.current_map_name) obj_pos = obj.fifeagent.behaviour.getLocation().getLayerCoordinates() player = self.model.game_state.getObjectById("PlayerCharacter") - is_player = obj.fifeagent.identifier == player.fifeagent.identifier + is_player = obj.general.identifier == player.general.identifier #TODO: Check all actions to be compatible with the grease components diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/objects/action.py --- a/src/parpg/objects/action.py Fri Sep 23 15:09:02 2011 +0200 +++ b/src/parpg/objects/action.py Sat Sep 24 15:48:24 2011 +0200 @@ -383,7 +383,7 @@ def execute(self): real_item = self.item.containable player = self.model.game_state.getObjectById("PlayerCharacter") - self.model.moveObject(self.item.fifeagent.identifier, None) + self.model.moveObject(self.item.general.identifier, None) container.put_item(player.container, real_item) super(PickUpAction, self).execute() diff -r a85d58fcd253 -r 9b5498e3bda0 src/parpg/world.py --- a/src/parpg/world.py Fri Sep 23 15:09:02 2011 +0200 +++ b/src/parpg/world.py Sat Sep 24 15:48:24 2011 +0200 @@ -12,6 +12,7 @@ def configure(self): """Configure the game world's components, systems and renderers""" + self.components.general = components.General() self.components.characterstats = components.CharacterStatistics() self.components.containable = components.Containable() self.components.container = components.Container()