changeset 102:2eb316546eae

Removed old objects code.
author KarstenBock@gmx.net
date Thu, 29 Sep 2011 18:15:12 +0200
parents 824f3068ef2a
children 57f1cff9a75d
files objects/__init__.py objects/actors.py objects/base.py objects/composed.py objects/containers.py objects/doors.py objects/items.py
diffstat 7 files changed, 0 insertions(+), 1272 deletions(-) [+]
line wrap: on
line diff
--- a/objects/__init__.py	Thu Sep 29 18:09:56 2011 +0200
+++ b/objects/__init__.py	Thu Sep 29 18:15:12 2011 +0200
@@ -12,43 +12,3 @@
 
 #   You should have received a copy of the GNU General Public License
 #   along with PARPG.  If not, see <http://www.gnu.org/licenses/>.
-
-import containers
-import doors
-import actors
-import items
-import sys
-
-OBJECT_MODULES = [containers, actors, doors, items]
-
-def getAllObjects ():
-    """Returns a dictionary with the names of the concrete game object classes
-       mapped to the classes themselves"""
-    result = {}
-    for module in OBJECT_MODULES:
-        for class_name in module.__all__:
-            result[class_name] = getattr (module, class_name)
-    return result
-
-def createObject(info, 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 type and ID, which every game_obj needs.
-    extra = extra or {}
-    try:
-        obj_type = info.pop('type')
-        ID = info.pop('id')
-    except KeyError:
-        sys.stderr.write("Error: Game object missing type or id.")
-        sys.exit(False)
-
-    # add the extra info
-    for key, val in extra.items():
-        info[key] = val
-
-    # this is for testing purposes
-    return getAllObjects()[obj_type](ID, **info)
--- a/objects/actors.py	Thu Sep 29 18:09:56 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,414 +0,0 @@
-#   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 <http://www.gnu.org/licenses/>.
-
-from random import randrange
-
-
-from fife import fife
-
-from base import GameObject, Living, Scriptable, CharStats
-from composed import CarryableItem
-from parpg.inventory import Inventory
-
-"""All actors go here. Concrete classes only."""
-
-__all__ = ["PlayerCharacter", "NonPlayerCharacter", ]
-
-_AGENT_STATE_NONE, _AGENT_STATE_IDLE, _AGENT_STATE_APPROACH, _AGENT_STATE_RUN, _AGENT_STATE_WANDER, _AGENT_STATE_TALK = xrange(6)
-
-class ActorBehaviour (fife.InstanceActionListener):
-    """Fife agent listener"""
-    def __init__(self, layer):
-        fife.InstanceActionListener.__init__(self)
-        self.layer = layer
-        self.agent = None
-        self.state = None
-        self.speed = 0
-        self.idle_counter = 1
-    
-    def attachToLayer(self, agent_ID):
-        """Attaches to a certain layer
-           @type agent_ID: String
-           @param agent_ID: ID of the layer to attach to.
-           @return: None"""
-        self.agent = self.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.ID)
-        self.agent.addActionListener(self)
-        self.state = _AGENT_STATE_NONE
-        self.idle_counter = 1
-    
-    def idle(self):
-        """@return: None"""
-        self.state = _AGENT_STATE_IDLE
-        self.agent.act('stand', self.agent.getFacingLocation())
-
-    def onInstanceActionFinished(self, instance, action):
-        pass
-
-class PCBehaviour (ActorBehaviour):
-    def __init__(self, parent=None, layer=None):
-        super(PCBehaviour, self).__init__(layer)        
-        self.parent = parent
-        self.idle_counter = 1
-        self.speed = 0
-        self.nextAction = None
-        self.agent = None
-        
-    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()
-            
-        if(action.getId() != 'stand'):
-            self.idle_counter = 1
-        else:
-            self.idle_counter += 1            
-
-
-class NPCBehaviour(ActorBehaviour):
-    def __init__(self, Parent=None, Layer=None):
-        super(NPCBehaviour, self).__init__(Layer)
-        
-        self.parent = Parent
-        self.state = _AGENT_STATE_NONE
-        self.pc = None
-        self.target_loc = None
-        self.nextAction = None
-        
-        # hard code these for now
-        self.distRange = (2, 4)
-        # these are parameters to lower the rate of wandering
-        # wander rate is the number of "IDLEs" before a wander step
-        # this could be set for individual NPCs at load time
-        # or thrown out altogether.
-        self.wanderCounter = 0
-        self.wanderRate = 9
-        
-    def getTargetLocation(self):
-        """@rtype: fife.Location
-           @return: NPC's position"""
-        x = self.getX()
-        y = self.getY()
-        if self.state == _AGENT_STATE_WANDER:
-            """ Random Target Location """
-            l = [0, 0]
-            for i in range(len(l)):
-                sign = randrange(0, 2)
-                dist = randrange(self.distRange[0], self.distRange[1])
-                if sign == 0:
-                    dist *= -1
-                l[i] = dist
-            x += l[0]
-            y += l[1]
-            # Random walk is
-            # rl = randint(-1, 1);ud = randint(-1, 1);x += rl;y += ud
-        l = fife.Location(self.agent.getLocation())
-        l.setLayerCoordinates(fife.ModelCoordinate(x, y))
-        return l
-
-    def onInstanceActionFinished(self, instance, action):
-        """What the NPC does when it has finished an action.
-           Called by the engine and required for InstanceActionListeners.
-           @type instance: fife.Instance
-           @param instance: self.agent (the NPC listener is listening for this
-                                        instance)
-           @type action: ???
-           @param action: ???
-           @return: None"""
-        if self.state == _AGENT_STATE_WANDER:
-            self.target_loc = self.getTargetLocation()
-        self.idle()
-        
-    
-    def idle(self):
-        """Controls the NPC when it is idling. Different actions
-           based on the NPC's state.
-           @return: None"""
-        if self.state == _AGENT_STATE_NONE:
-            self.state = _AGENT_STATE_IDLE
-            self.agent.act('stand', self.agent.getFacingLocation())
-        elif self.state == _AGENT_STATE_IDLE:
-            if self.wanderCounter > self.wanderRate:
-                self.wanderCounter = 0
-                self.state = _AGENT_STATE_WANDER
-            else:
-                self.wanderCounter += 1
-                self.state = _AGENT_STATE_NONE
-            
-            self.target_loc = self.getTargetLocation()
-            self.agent.act('stand', self.agent.getFacingLocation())
-        elif self.state == _AGENT_STATE_WANDER:
-            self.parent.wander(self.target_loc)
-            self.state = _AGENT_STATE_NONE
-        elif self.state == _AGENT_STATE_TALK:
-            self.agent.act('stand', self.pc.getLocation())
-            
-class CharacterBase(GameObject, CharStats, Living):
-    """Base class for Characters"""
-    def __init__(self, ID, agent_layer=None, inventory=None, text="",
-                 primary_stats=None, secondary_stats=None, **kwargs):
-        GameObject.__init__(self, ID, text=text, **kwargs)
-        CharStats.__init__(self, **kwargs)
-        Living.__init__(self, **kwargs)
-        self.statistics = {}
-        if primary_stats is not None:
-            for primary_stat in primary_stats:
-                name = primary_stat.name
-                self.statistics[name] = primary_stat
-        if secondary_stats is not None:
-            for secondary_stat in primary_stats:
-                long_name = secondary_stat.long_name
-                self.statistics[long_name] = secondary_stat
-                short_name = secondary_stat.short_name
-                self.statistics[short_name] = secondary_stat
-                secondary_stat.attach(self)
-        self.behaviour = None
-        if inventory == None:
-            self.inventory = Inventory()
-        else:
-            self.inventory = inventory
-        self.state = _AGENT_STATE_NONE
-        self.layer_id = agent_layer.getId()
-        self.createBehaviour(agent_layer)
-    
-    def createBehaviour(self, layer):
-        """Creates the behaviour for this actor.
-           @return: None"""
-        pass
-    
-    def setup(self):
-        """@return: None"""
-        self.behaviour.attachToLayer(self.ID)
-
-    def start(self):
-        """@return: None"""
-        self.behaviour.idle()
-
-    def teleport(self, location):
-        """Teleports a Character instantly to the given location.
-           @type location: fife.Location
-           @param location: Target coordinates for Character.
-           @return: None"""
-        self.state = _AGENT_STATE_IDLE
-        self.behaviour.nextAction = None 
-        self.behaviour.agent.setLocation(location)
-
-    def give (self, item, actor):
-        """Gives the specified item to the different actor. Raises an exception if the item was invalid or not found
-           @type item: Carryable
-           @param item: The item object to give
-           @param actor: Person to give item to"""
-        if item == None: 
-            raise ValueError("I don't have %s" % item.name)
-        self.inventory.takeItem(item)
-        actor.inventory.placeItem(item)           
-        
-    def hasItem(self, item_type):
-        """Returns wether an item is present in the players inventory or not
-        @param item_type: ID of the item
-        @type item_type: str
-        @return: True when the item is present, False when not"""
-        return self.inventory.findItem(item_type=item_type)
-
-    def itemCount(self, item_type=""):
-        """Returns number of all items or items specified by item_type 
-        the player has.
-        @param item_type: ID of the item, can be empty
-        @type item_type: str
-        @return: Number of items"""
-        return self.inventory.count(item_type)
-
-    def getLocation(self):
-        """Get the NPC's position as a fife.Location object. Basically a
-           wrapper.
-           @rtype: fife.Location
-           @return: the location of the NPC"""
-        return self.behaviour.agent.getLocation()
-    
-    def run(self, location):
-        """Makes the PC run to a certain location
-           @type location: fife.ScreenPoint
-           @param location: Screen position to run to.
-           @return: None"""
-        self.state = _AGENT_STATE_RUN
-        self.behaviour.nextAction = None
-        self.behaviour.agent.move('run', location, self.behaviour.speed + 1)
-
-    def walk(self, location):
-        """Makes the PC walk to a certain location.
-           @type location: fife.ScreenPoint
-           @param location: Screen position to walk to.
-           @return: None"""
-        self.state = _AGENT_STATE_RUN
-        self.behaviour.nextAction = None 
-        self.behaviour.agent.move('walk', location, self.behaviour.speed - 1)
-
-    def getStateForSaving(self):
-        """Returns state for saving
-        """
-        ret_dict = GameObject.getStateForSaving(self)
-        ret_dict["Inventory"] = self.inventory.serializeInventory()
-        return ret_dict
-
-    def _getCoords(self):
-        """Get-er property function"""
-        return (self.getLocation().getMapCoordinates().x,
-                self.getLocation().getMapCoordinates().y)
-    
-    def _setCoords(self, coords):
-        """Set-er property function"""
-        map_coords = self.getLocation().getMapCoordinates()
-        map_coords.X, map_coords.Y = float(coords[0]), float (coords[1])
-        self.teleport(map_coords)
-    
-    coords = property (_getCoords, _setCoords,
-        doc="Property allowing you to get and set the object's \
-                coordinates via tuples")
-           
-class PlayerCharacter (CharacterBase):
-    """PC class"""
-    def __init__ (self, ID, agent_layer=None, inventory=None,
-                  text="Its you. Who would've thought that?", **kwargs):
-        if inventory == None:
-            inventory = Inventory()
-            inventory.placeItem(CarryableItem(ID=456, name="Dagger123"))
-            inventory.placeItem(CarryableItem(ID=555, name="Beer"))
-            inventory.placeItem(CarryableItem(ID=616,
-                                    name="Pamphlet",
-                                    image="/gui/inv_images/inv_pamphlet.png"))
-        CharacterBase.__init__(self, ID, agent_layer, inventory, text, **kwargs)
-        self.people_i_know = set()
-        self.attributes.append("PC")
-  
-    def getStateForSaving(self):
-        """Returns state for saving
-        """
-        ret_dict = super(PlayerCharacter, self).getStateForSaving()
-        ret_dict["PeopleKnown"] = self.people_i_know
-        return ret_dict
-    
-    def meet(self, npc):
-        """Record that the PC has met a certain NPC
-           @type npc: str
-           @param npc: The NPC's name or id"""
-        if npc in self.people_i_know:
-            # we could raise an error here, but should probably be a warn
-            # raise RuntimeError("I already know %s" % npc)
-            return
-        self.people_i_know.add(npc)
-
-    def met(self, npc):
-        """Indicate whether the PC has met this npc before
-           @type npc: str
-           @param npc: The NPC's name or id
-           @return: None"""
-        return npc in self.people_i_know
-
-    def createBehaviour(self, layer):
-        """Creates the behaviour for this actor.
-           @return: None"""
-        self.behaviour = PCBehaviour(self, layer)
- 
-    def approach(self, location, action=None):
-        """Approaches a location and then perform an action (if set).
-           @type loc: fife.Location
-           @param loc: the location to approach
-           @type action: Action
-           @param action: The action to schedule for execution after the approach.
-           @return: None"""
-        self.state = _AGENT_STATE_APPROACH
-        self.behaviour.nextAction = action
-        boxLocation = tuple([int(float(i)) for i in location])
-        l = fife.Location(self.behaviour.agent.getLocation())
-        l.setLayerCoordinates(fife.ModelCoordinate(*boxLocation))
-        self.behaviour.agent.move('run', l, self.behaviour.speed + 1)
-    
-class NonPlayerCharacter(CharacterBase, Scriptable):
-    """NPC class"""
-    def __init__(self, ID, agent_layer=None, name='NPC', \
-                 text='A nonplayer character', inventory=None,
-                 real_name='NPC', dialogue=None, **kwargs):
-        # init game object
-        CharacterBase.__init__(self, ID, agent_layer=agent_layer,
-                               inventory=inventory, name=name,
-                               real_name=real_name, text=text, **kwargs)
-        Scriptable.__init__(self, **kwargs)
-
-        self.attributes.append("NPC")
-        self.dialogue = dialogue
-
-    def prepareStateForSaving(self, state):
-        """Prepares state for saving
-        @type state: dictionary
-        @param state: State of the object  
-        """
-        CharacterBase.prepareStateForSaving(self, state)
-        del state["behaviour"]
-
-    def getStateForSaving(self):
-        """Returns state for saving
-        """
-        ret_dict = CharacterBase.getStateForSaving(self)
-        ret_dict["Lives"] = self.lives
-        ret_dict["State"] = self.behaviour.state
-        return ret_dict
-
-    def createBehaviour(self, layer):
-        """Creates the behaviour for this actor.
-           @return None """
-        self.behaviour = NPCBehaviour(self, layer)
-
-    def wander(self, location):
-        """Nice slow movement for random walking.
-           @type location: fife.Location
-           @param location: Where the NPC will walk to.
-           @return: None"""
-        self.behaviour.agent.move('walk', location, self.behaviour.speed - 1)
-
-    def talk(self, pc):
-        """Makes the NPC ready to talk to the PC
-           @return: None"""
-        self.behaviour.state = _AGENT_STATE_TALK
-        self.behaviour.pc = pc.behaviour.agent
-        self.behaviour.idle()
--- a/objects/base.py	Thu Sep 29 18:09:56 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,508 +0,0 @@
-#   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 <http://www.gnu.org/licenses/>.
-
-"""Containes classes defining the base properties of all interactable in-game 
-   objects (such as Carryable, Openable, etc. These are generally independent 
-   classes, which can be combined in almost any way and order. 
-
-   Some rules that should be followed when CREATING base property classes:
-   
-   1. If you want to support some custom initialization arguments, 
-      always define them as keyword ones. Only GameObject would use 
-      positional arguments.
-   2. In __init__() **ALWAYS** call the parent's __init__(**kwargs), preferably 
-      *at the end* of your __init__() (makes it easier to follow)
-   3. There should always be an attributes.append(x) call on __init__ 
-      (where X is the name of the class)
-
-   EXAMPLE:
-
-   class Openable(object):
-       def __init__ (self, is_open = True, **kwargs):
-           self.attribbutes.append("openable")
-           self.is_open = is_open
-           super(Openable,self).__init__ (**kwargs)
-        
-
-   Some rules are to be followed when USING the base classes to make composed 
-   ones:
-
-   1. The first parent should always be the base GameObject class
-   2. Base classes other than GameObject can be inherited in any order
-   3. The __init__ functoin of the composed class should always invoke the
-      parent's __init__() *before* it starts customizing any variables.
-
-   EXAMPLE:
-
-   class TinCan (GameObject, Container, Scriptable, Destructable, Carryable):
-       def __init__ (self, *args, **kwargs):
-           super(TinCan,self).__init__ (*args, **kwargs)
-           self.name = 'Tin Can'"""
-         
-class BaseObject(object):
-    """A base class that supports dynamic attributes functionality"""
-    def __init__ (self):
-        if not self.__dict__.has_key("attributes"):
-            self.attributes = []
-    
-    def trueAttr(self, attr):
-        """Method that checks if the instance has an attribute"""
-        return attr in self.attributes
-
-    def getStateForSaving(self):
-        """Returns state for saving
-        """
-        state = {}
-        state["attributes"] = self.attributes
-        return state
-
-class DynamicObject (BaseObject):
-    """Class with basic attributes"""
-    def __init__ (self, name="Dynamic object", real_name=None, image=None, **kwargs):
-        """Initialise minimalistic set of data
-           @type name: String
-           @param name: Object display name
-           @type image: String or None
-           @param name: Filename of image to use in inventory"""
-        BaseObject.__init__(self)
-        self.name = name
-        self.real_name = real_name or name
-        self.image = image
-
-    def prepareStateForSaving(self, state):
-        """Prepares state for saving
-        @type state: dictionary
-        @param state: State of the object  
-        """
-        pass
-    
-    def restoreState(self, state):
-        """Restores a state from a saved state
-        @type state: dictionary
-        @param state: Saved state  
-        """
-        self.__dict__.update(state)
-
-    def __getstate__(self):
-        odict = self.__dict__.copy()
-        self.prepareStateForSaving(odict)
-        return odict
-    
-    def __setstate__(self, state):
-        self.restoreState(state)
-    
-    def getStateForSaving(self):
-        """Returns state for saving
-        """
-        state = BaseObject.getStateForSaving(self)
-        state["Name"] = self.name
-        state["RealName"] = self.real_name
-        state["Image"] = self.image
-        return state
-
-class GameObject (DynamicObject):
-    """A base class to be inherited by all game objects. This must be the
-       first class (left to right) inherited by any game object."""
-    def __init__ (self, ID, gfx = None, xpos = 0.0, ypos = 0.0, map_id = None, 
-                  blocking=True, name="Generic object", real_name="Generic object", text="Item description",
-                  desc="Detailed description", **kwargs):
-        """Set the basic values that are shared by all game objects.
-           @type ID: String
-           @param ID: Unique object identifier. Must be present.
-           @type gfx: Dictionary
-           @param gfx: Dictionary with graphics for the different contexts       
-           @type coords 2-item tuple
-           @param coords: Initial coordinates of the object.
-           @type map_id: String
-           @param map_id: Identifier of the map where the object is located
-           @type blocking: Boolean
-           @param blocking: Whether the object blocks character movement
-           @type name: String
-           @param name: The display name of this object (e.g. 'Dirty crate')
-           @type text: String
-           @param text: A longer description of the item
-           @type desc: String
-           @param desc: A long description of the item that is displayed when it is examined
-           """
-        DynamicObject.__init__(self, name, real_name, **kwargs)
-        self.ID = ID
-        self.gfx = gfx or {}
-        self.X = xpos
-        self.Y = ypos
-        self.map_id = map_id
-        self.blocking = True
-        self.text = text
-        self.desc = desc
-        
-    def _getCoords(self):
-        """Get-er property function"""
-        return (self.X, self.Y)
-    
-    def _setCoords(self, coords):
-        """Set-er property function"""
-        self.X, self.Y = float(coords[0]), float (coords[1])
-        
-    coords = property (_getCoords, _setCoords, 
-        doc = "Property allowing you to get and set the object's \
-                coordinates via tuples")
-    
-    def __repr__(self):
-        """A debugging string representation of the object"""
-        return "<%s:%s>" % (self.name, self.ID)
-
-    def getStateForSaving(self):
-        """Returns state for saving
-        """
-        state = super(GameObject, self).getStateForSaving()
-        state["ObjectModel"] = self.gfx
-        state["Text"] = self.text
-        state["Desc"] = self.desc
-        state["Position"] = list(self.coords)
-        return state
-
-
-class Scriptable (BaseObject):
-    """Allows objects to have predefined parpg executed on certain events"""
-    def __init__ (self, parpg = None, **kwargs):
-        """Init operation for scriptable objects
-           @type parpg: Dictionary
-           @param parpg: Dictionary where the event strings are keys. The 
-           values are 3-item tuples (function, positional_args, keyword_args)"""
-        BaseObject.__init__(self)
-        self.attributes.append("scriptable")
-        self.parpg = parpg or {}
-        
-    def runScript (self, event):
-        """Runs the script for the given event"""
-        if event in self.parpg and self.parpg[event]:
-            func, args, kwargs = self.parpg[event]
-            func (*args, **kwargs)
-            
-    def setScript (self, event, func, args = None , kwargs = None):
-        """Sets a script to be executed for the given event."""
-        args = args or {}
-        kwargs = kwargs or {}
-        self.parpg[event] = (func, args, kwargs)
-
-class Openable(DynamicObject, Scriptable):
-    """Adds open() and .close() capabilities to game objects
-       The current state is tracked by the .is_open variable"""
-    def __init__(self, is_open = True, **kwargs):
-        """Init operation for openable objects
-           @type is_open: Boolean
-           @param is_open: Keyword boolean argument sets the initial state."""
-        DynamicObject.__init__(self, **kwargs)
-        Scriptable.__init__(self, **kwargs)
-        self.attributes.append("openable")
-        self.is_open = is_open
-    
-    def open(self):
-        """Opens the object, and runs an 'onOpen' script, if present"""
-        self.is_open = True
-        try:
-            if self.trueAttr ('scriptable'):
-                self.runScript('onOpen')
-        except AttributeError :
-            pass
-            
-    def close(self):
-        """Opens the object, and runs an 'onClose' script, if present"""
-        self.is_open = False
-        try:
-            if self.trueAttr ('scriptable'):
-                self.runScript('onClose')
-        except AttributeError :
-            pass
-        
-class Lockable (Openable):
-    """Allows objects to be locked"""
-    def __init__ (self, locked = False, is_open = True, **kwargs):
-        """Init operation for lockable objects
-           @type locked: Boolean
-           @param locked: Keyword boolen argument sets the initial locked state.
-           @type is_open: Boolean
-           @param is_open: Keyword boolean argument sets the initial open state.
-                           It is ignored if locked is True -- locked objects
-                           are always closed."""
-        self.attributes.append("lockable")
-        self.locked = locked
-        if locked :
-            is_open = False
-        Openable.__init__( self, is_open, **kwargs )
-        
-    def unlock (self):
-        """Handles unlocking functionality"""
-        self.locked = False      
-        
-    def lock (self):
-        """Handles  locking functionality"""
-        self.close()
-        self.locked = True
-        
-    def open (self, *args, **kwargs):
-        """Adds a check to see if the object is unlocked before running the
-           .open() function of the parent class"""
-        if self.locked:
-            raise ValueError ("Open failed: object locked")
-        super (Lockable, self).open(*args, **kwargs)
-        
-class Carryable (DynamicObject):
-    """Allows objects to be stored in containers"""
-    def __init__ (self, weight=0.0, bulk=0.0, **kwargs):
-        DynamicObject.__init__(self, **kwargs)
-        self.attributes.append("carryable")
-        self.in_container = None
-        self.on_map = None
-        self.agent = None
-        self.weight = weight
-        self.bulk = bulk
-
-    def getInventoryThumbnail(self):
-        """Returns the inventory thumbnail of the object"""
-        # TODO: Implement properly after the objects database is in place
-        if self.image == None:
-            return "gui/inv_images/inv_litem.png"
-        else:
-            return self.image
-    
-class Container (DynamicObject, Scriptable):
-    """Gives objects the capability to hold other objects"""
-    class TooBig(Exception):
-        """Exception to be raised when the object is too big
-        to fit into container"""
-        pass
-    
-    class SlotBusy(Exception):
-        """Exception to be raised when the requested slot is occupied"""
-        pass
-    
-    class ItemSelf(Exception):
-        """Exception to be raised when trying to add the container as an item"""
-        pass
-  
-    def __init__ (self, capacity = 0, items = None, **kwargs):
-        DynamicObject.__init__(self, **kwargs)
-        Scriptable.__init__(self, **kwargs)
-        self.attributes.append("container")
-        self.items = {}
-        self.capacity = capacity
-        if items:
-            for item in items:
-                self.placeItem(item)
-        
-    def placeItem (self, item, index=None):
-        """Adds the provided carryable item to the inventory. 
-           Runs an 'onStoreItem' script, if present""" 
-        if item is self:
-            raise self.ItemSelf("Paradox: Can't contain myself")    
-        if not item.trueAttr ('carryable'):
-            raise TypeError ('%s is not carryable!' % item)
-        if self.capacity and self.getContentsBulk()+item.bulk > self.capacity:
-            raise self.TooBig ('%s is too big to fit into %s' % (item, self))
-        item.in_container = self
-        if index == None:
-            self._placeAtVacant(item)
-        else:
-            if index in self.items :
-                raise self.SlotBusy('Slot %d is busy in %s' % (index, 
-                                                               self.name))
-            self.items[index] = item
-
-        # Run any parpg associated with storing an item in the container
-        try:
-            if self.trueAttr ('scriptable'):
-                self.runScript('onPlaceItem')
-        except AttributeError :
-            pass
-
-    def _placeAtVacant(self, item):
-        """Places an item at a vacant slot"""
-        vacant = None
-        for i in range(len(self.items)):
-            if i not in self.items :
-                vacant = i
-        if vacant == None :
-            vacant = len(self.items)
-        self.items[vacant] = item
-    
-    def takeItem (self, item):
-        """Takes the listed item out of the inventory. 
-           Runs an 'onTakeItem' script"""        
-        if not item in self.items.values():
-            raise ValueError ('I do not contain this item: %s' % item)
-        del self.items[self.items.keys()[self.items.values().index(item)]]
-
-        # Run any parpg associated with popping an item out of the container
-        try:
-            if self.trueAttr ('scriptable'):
-                self.runScript('onTakeItem')
-        except AttributeError :
-            pass
-    
-    def replaceItem(self, old_item, new_item):
-        """Replaces the old item with the new one
-        @param old_item: Old item which is removed
-        @type old_item: Carryable
-        @param new_item: New item which is added
-        @type new_item: Carryable
-        """
-        old_index = self.indexOf(old_item.ID)
-        self.removeItem(old_item)
-        self.placeItem(new_item, old_index)
-        
-    def removeItem(self, item):
-        """Removes an item from the container, basically the same as 'takeItem'
-        but does run a different script. This should be used when an item is
-        destroyed rather than moved out.
-        Runs 'onRemoveItem' script
-        """
-        if not item in self.items.values():
-            raise ValueError ('I do not contain this item: %s' % item)
-        del self.items[self.items.keys()[self.items.values().index(item)]]
-
-        # Run any parpg associated with popping an item out of the container
-        try:
-            if self.trueAttr ('scriptable'):
-                self.runScript('onRemoveItem')
-        except AttributeError :
-            pass
-
-    def count (self, item_type = ""):
-        """Returns the number of items"""
-        if item_type:
-            ret_count = 0
-            for index in self.items :
-                if self.items[index].item_type == item_type:
-                    ret_count += 1
-            return ret_count
-        return len(self.items)   
-    
-    def getContentsBulk(self):
-        """Bulk of the container contents"""
-        return sum((item.bulk for item in self.items.values()))
-
-    def getItemAt(self, index):
-        return self.items[index]
-    
-    def indexOf(self, ID):
-        """Returns the index of the item with the passed ID"""
-        for index in self.items :
-            if self.items[index].ID == ID:
-                return index
-        return None
-
-    def findItemByID(self, ID):
-        """Returns the item with the passed ID"""
-        for i in self.items :
-            if self.items[i].ID == ID:
-                return self.items[i]
-        return None
-
-    def findItemByItemType(self, item_type):
-        """Returns the item with the passed item_type"""
-        for index in self.items :
-            if self.items[index].item_type == item_type:
-                return self.items[index]
-        return None
-
-    def findItem(self, **kwargs):
-        """Find an item in container by attributes. All params are optional.
-           @type name: String
-           @param name: If the name is non-unique, return first matching object
-           @type kind: String
-           @param kind: One of the possible object types
-           @return: The item matching criteria or None if none was found"""
-        for index in self.items :
-            if "name" in kwargs and self.items[index].name != kwargs["name"]:
-                continue
-            if "ID" in kwargs and self.items[index].ID != kwargs["ID"]:
-                continue
-            if "kind" in kwargs and not self.items[index].trueAttr(kwargs["kind"]):
-                continue
-            if "item_type" in kwargs and self.items[index].item_type != kwargs["item_type"]:
-                continue
-            return self.items[index]
-        return None    
-    
-    def serializeItems(self):
-        """Returns the items as a list"""
-        items = []
-        for index, item in self.items.iteritems():
-            item_dict = item.getStateForSaving()
-            item_dict["index"] = index
-            item_dict["type"] = item.item_type
-            items.append(item_dict)
-        return items
-    
-    def getStateForSaving(self):
-        """Returns state for saving
-        """
-        ret_state = DynamicObject.getStateForSaving(self)
-        ret_state["Items"] = self.serializeItems()
-        return ret_state
-        
-class Living (BaseObject):
-    """Objects that 'live'"""
-    def __init__ (self, **kwargs):
-        BaseObject.__init__(self)
-        self.attributes.append("living")
-        self.lives = True
-
-    def die(self):
-        """Kills the object"""
-        self.lives = False   
-
-class CharStats (BaseObject):
-    """Provides the object with character statistics"""
-    def __init__ (self, **kwargs):
-        BaseObject.__init__(self)
-        self.attributes.append("charstats")
-        
-class Wearable (BaseObject):
-    """Objects than can be weared"""
-    def __init__ (self, slots, **kwargs):
-        """Allows the object to be worn somewhere on the body (e.g. pants)"""
-        BaseObject.__init__(self)
-        self.attributes.append("wearable")
-        if isinstance(slots, tuple) :
-            self.slots = slots
-        else :
-            self.slots = (slots,)
-    
-class Usable (BaseObject):
-    """Allows the object to be used in some way (e.g. a Zippo lighter 
-       to make a fire)"""
-    def __init__ (self, actions = None, **kwargs):
-        BaseObject.__init__(self)
-        self.attributes.append("usable")
-        self.actions = actions or {}   
-        
-class Weapon (BaseObject):
-    """Allows the object to be used as a weapon"""
-    def __init__ (self, **kwargs):
-        BaseObject.__init__(self)
-        self.attributes.append("weapon")
-        
-class Destructable (BaseObject):
-    """Allows the object to be destroyed"""
-    def __init__ (self, **kwargs):
-        BaseObject.__init__(self)
-        self.attributes.append("destructable")
-        
-class Trapable (BaseObject):
-    """Provides trap slots to the object"""
-    def __init__ (self, **kwargs):
-        BaseObject.__init__(self)
-        self.attributes.append("trapable")
--- a/objects/composed.py	Thu Sep 29 18:09:56 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-#   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 <http://www.gnu.org/licenses/>.
-
-"""Composite game object classes are kept here"""
-
-from base import GameObject, Container, Lockable, \
-                Scriptable, Trapable, Destructable, Carryable, \
-                Usable
-
-class ImmovableContainer(GameObject, Container, Lockable, Scriptable, 
-                         Trapable, Destructable):
-    """Composite class that can be used for crates, chests, etc."""
-    def __init__ (self, **kwargs):
-        GameObject   .__init__(self, **kwargs)
-        Container    .__init__(self, **kwargs)
-        Lockable     .__init__(self, **kwargs)
-        Scriptable   .__init__(self, **kwargs)
-        Trapable    .__init__(self, **kwargs)
-        Destructable .__init__(self, **kwargs)
-        self.blocking = True
-
-class SingleItemContainer (Container) :
-    """Container that can only store a single item.
-       This class can represent single-item inventory slots"""
-    def __init__ (self, **kwargs):
-        Container.__init__(self, **kwargs)
-
-    def placeItem(self,item, index=None):
-        if len(self.items) > 0 :
-            raise self.SlotBusy ('%s is already busy' % self)
-        Container.placeItem(self, item)
-    
-class CarryableItem (GameObject, Carryable, Usable):
-    """Composite class that will be used for all carryable items"""
-    def __init__(self, item_type, **kwargs):
-        GameObject.__init__(self, **kwargs)
-        Carryable.__init__(self, **kwargs)
-        Usable.__init__(self, **kwargs)
-        self.item_type = item_type
-
-    def prepareStateForSaving(self, state):
-        """Prepares state for saving
-        @type state: dictionary
-        @param state: State of the object  
-        """
-        super(CarryableItem, self).prepareStateForSaving(state)
-        if state.has_key("in_container"):
-            del state["in_container"]
-        if state.has_key("on_map"):
-            del state["on_map"]
-        if state.has_key("agent"):
-            del state["agent"]
-
-    def getStateForSaving(self):
-        """Returns state for saving
-        @type state: dictionary
-        @param state: State of the object  
-        """
-        ret_dict = self.__dict__.copy()
-        self.prepareStateForSaving(ret_dict)
-        return ret_dict
-
-class CarryableContainer(Container, CarryableItem):
-    """Composite class that will be used for backpack, pouches, etc."""
-    def __init__ (self, item_type, **kwargs):
-        Container.__init__(self, **kwargs)
-        CarryableItem.__init__(self, item_type, **kwargs)
-        self.own_bulk = 0
-        self.own_weight = 0
-
-    def getWeight(self):
-        """Resulting weight of a container"""
-        return sum((item.weight for item in self.items.values()), 
-                   self.own_weight)
-
-    def setWeight(self, weight):
-        """Set container's own weight. 
-        For compatibility with inherited methods"""
-        self.own_weight = weight
-
-    weight = property(getWeight, setWeight, "Total weight of container")
-
-    def getBulk(self):
-        """Resulting bulk of container"""
-        return self.getContentsBulk()+self.own_bulk
-
-    def setBulk(self, bulk):
-        """Set container's own bulk. For compatibility with inherited methods"""
-        self.own_bulk = bulk
-
-    bulk = property(getBulk, setBulk, "Total bulk of container")
-    
-    def __repr__(self):
-        return "[%s" % self.name + str(reduce((lambda a, b: a + ', ' + \
-                                    str(self.items[b])), self.items, "")) + " ]"
-
-    def getStateForSaving(self):
-        """Returns state for saving
-        @type state: dictionary
-        @param state: State of the object  
-        """
-        state = Container.getStateForSaving(self)
-        if not state.has_key("attributes"):
-            state["attributes"] = []
-        state["attributes"].append("Container")
-        state.update(CarryableItem.getStateForSaving(self))
-        return state
-
-class CarryableSingleItemContainer (SingleItemContainer, CarryableContainer) :
-    """Container that can only store a single item.
-       This class can represent single-item inventory slots"""
-    def __init__ (self, item_type, **kwargs):
-        SingleItemContainer.__init__(self, **kwargs)
-        CarryableContainer.__init__(self, item_type, **kwargs)
-        
-class Door(GameObject, Lockable, Scriptable, Trapable):
-    """Composite class that can be used to create doors on a map."""
-    def __init__ (self, target_map_name = 'my-map',
-                  target_x = 0.0, target_y = 0.0, **kwargs):
-        GameObject.__init__(self, **kwargs)
-        Lockable.__init__(self, **kwargs)
-        Scriptable.__init__(self, **kwargs)
-        Trapable.__init__(self, **kwargs)
-        self.attributes.append("door")
-        self.target_map_name = target_map_name
-        self.target_pos = (target_x, target_y)
-        self.blocking = True
-
-    def getStateForSaving(self):
-        """Returns state for saving
-        """
-        ret_dict = super(Door, self).getStateForSaving()
-        return ret_dict
--- a/objects/containers.py	Thu Sep 29 18:09:56 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-#   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 <http://www.gnu.org/licenses/>.
-
-"""Containes classes defining concrete container game objects like crates,
-   barrels, chests, etc."""
-
-__all__ = ["WoodenCrate", "Footlocker"]
-
-_AGENT_STATE_NONE, _AGENT_STATE_OPENED, _AGENT_STATE_CLOSED, \
-_AGENT_STATE_OPENING, _AGENT_STATE_CLOSING = xrange(5)
-
-from composed import ImmovableContainer
-from fife import fife
-
-class WoodenCrate (ImmovableContainer):
-    def __init__(self, object_id, name = 'Wooden Crate',
-                 text = 'A battered crate', gfx = 'crate', **kwargs):
-        ImmovableContainer.__init__(self, ID = object_id, name = name, 
-                                    gfx = gfx, text = text, **kwargs)
-        
-class ContainerBehaviour(fife.InstanceActionListener):
-    def __init__(self, parent = None, agent_layer = None):
-        fife.InstanceActionListener.__init__(self)
-        self.parent = parent
-        self.layer = agent_layer
-        self.state = _AGENT_STATE_CLOSED
-        self.agent = None
-
-    def attachToLayer(self, agent_id):
-        """ Attaches to a certain layer
-            @type agent_id: String
-            @param agent_id: ID of the layer to attach to.
-            @return: None"""
-        self.agent = self.layer.getInstance(agent_id)
-        self.agent.addActionListener(self)
-        self.state = _AGENT_STATE_CLOSED
-        self.agent.act('closed', self.agent.getLocation())
-        
-    def onInstanceActionFinished(self, instance, action):
-        """What the Actor does when it has finished an action.
-           Called by the engine and required for InstanceActionListeners.
-           @type instance: fife.Instance
-           @param instance: self.agent (the Actor listener is listening for this
-            instance)
-           @type action: ???
-           @param action: ???
-           @return: None"""
-        if self.state == _AGENT_STATE_OPENING:
-            self.agent.act('opened', self.agent.getFacingLocation(), True)
-            self.state = _AGENT_STATE_OPENED
-        if self.state == _AGENT_STATE_CLOSING:
-            self.agent.act('closed', self.agent.getFacingLocation(), True)
-            self.state = _AGENT_STATE_CLOSED
-        
-    def open (self):
-        if self.state != _AGENT_STATE_OPENED and self.state != \
-                                                _AGENT_STATE_OPENING:
-            self.agent.act('open', self.agent.getLocation())
-            self.state = _AGENT_STATE_OPENING
-
-    def close(self):
-        if self.state != _AGENT_STATE_CLOSED and self.state != \
-                                                _AGENT_STATE_CLOSING:
-            self.agent.act('close', self.agent.getLocation())
-            self.state = _AGENT_STATE_CLOSING  
-    
-class Footlocker(ImmovableContainer):
-    def __init__ (self, object_id, agent_layer=None, name = 'Footlocker',
-                  text = 'A Footlocker', gfx = 'lock_box_metal01', **kwargs):
-        ImmovableContainer.__init__(self, ID = object_id, name = name, 
-                                    gfx = gfx, text = text, **kwargs)
-        self.behaviour = None
-
-        self.attributes.append("AnimatedContainer")
-        self.createBehaviour(agent_layer)        
-        
-    def prepareStateForSaving(self, state):
-        """Prepares state for saving
-        @type state: dictionary
-        @param state: State of the object  
-        """
-        ImmovableContainer.prepareStateForSaving(self, state)
-        del state["behaviour"]
-    
-    def createBehaviour(self, layer):
-        self.behaviour = ContainerBehaviour(self, layer)
-
-    def setup(self):
-        """@return: None"""
-        self.behaviour.attachToLayer(self.ID)
-
-    def open (self):
-        super (Footlocker, self).open()
-        self.behaviour.open()
-
-    def close(self):
-        super (Footlocker, self).close()
-        self.behaviour.close()
--- a/objects/doors.py	Thu Sep 29 18:09:56 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#   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 <http://www.gnu.org/licenses/>.
-
-"""Containes classes defining concrete door game objects."""
-
-__all__ = ["ShantyDoor", ]
-
-from composed import Door
-
-class ShantyDoor(Door):
-    def __init__ (self, ID, name = 'Shanty Door', text = 'A door',
-                   gfx = 'shanty-door', target_map_name = 'my-map',
-                   target_x = 0.0, target_y = 0.0, **kwargs):
-        Door.__init__(self, ID = ID, name = name, text = text, gfx = gfx,
-                      target_map_name = target_map_name,
-                      target_x = target_x,
-                      target_y = target_y, **kwargs)
--- a/objects/items.py	Thu Sep 29 18:09:56 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#   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 <http://www.gnu.org/licenses/>.
-
-__all__ = ["MapItem", ]
-
-from composed import CarryableItem
-
-class MapItem(CarryableItem):
-    """Item that is lying on a map"""
-    def __init__(self, ID, item_type, item, name = 'Item', text = 'An item',
-                   gfx = 'item', **kwargs):
-        CarryableItem.__init__(self, ID = ID, item_type = item_type, name = name, 
-                               text = text, gfx = gfx, **kwargs)
-        self.item = item