Index: code/trunk/src/orxonox/interfaces/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/interfaces/CMakeLists.txt	(revision 6417)
+++ code/trunk/src/orxonox/interfaces/CMakeLists.txt	(revision 6524)
@@ -1,4 +1,5 @@
 ADD_SOURCE_FILES(ORXONOX_SRC_FILES
   InterfaceCompilation.cc
+  Pickupable.cc
   RadarViewable.cc
 )
Index: code/trunk/src/orxonox/interfaces/InterfaceCompilation.cc
===================================================================
--- code/trunk/src/orxonox/interfaces/InterfaceCompilation.cc	(revision 6417)
+++ code/trunk/src/orxonox/interfaces/InterfaceCompilation.cc	(revision 6524)
@@ -34,4 +34,5 @@
 
 #include "GametypeMessageListener.h"
+#include "PickupCarrier.h"
 #include "PlayerTrigger.h"
 #include "RadarListener.h"
@@ -51,5 +52,35 @@
         RegisterRootObject(GametypeMessageListener);
     }
+    
+    //----------------------------
+    // PickupCarrier
+    //----------------------------
+    PickupCarrier::PickupCarrier()
+    {
+        RegisterRootObject(PickupCarrier);
+        
+    }
+    
+    PickupCarrier::~PickupCarrier()
+    {
+        for(std::set<Pickupable*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            (*it)->destroy();
+        }
+        
+        this->pickups_.clear();
+    }
 
+    //----------------------------
+    // PlayerTrigger
+    //----------------------------
+    PlayerTrigger::PlayerTrigger()
+    {
+        RegisterRootObject(PlayerTrigger);
+
+        this->player_ = NULL;
+        this->isForPlayer_ = true;
+    }
+    
     //----------------------------
     // RadarListener
@@ -83,14 +114,3 @@
         RegisterRootObject(NotificationListener);
     }
-
-    //----------------------------
-    // PlayerTrigger
-    //----------------------------
-    PlayerTrigger::PlayerTrigger()
-    {
-        RegisterRootObject(PlayerTrigger);
-
-        this->player_ = NULL;
-        this->isForPlayer_ = true;
-    }
 }
Index: code/trunk/src/orxonox/interfaces/PickupCarrier.h
===================================================================
--- code/trunk/src/orxonox/interfaces/PickupCarrier.h	(revision 6524)
+++ code/trunk/src/orxonox/interfaces/PickupCarrier.h	(revision 6524)
@@ -0,0 +1,190 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 2
+ *   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, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the PickupCarrier class.
+*/
+
+#ifndef _PickupCarrier_H__
+#define _PickupCarrier_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include <set>
+#include "Pickupable.h"
+#include "core/Identifier.h"
+
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+
+    class Pickup;
+    class HealthPickup;
+    class MetaPickup;
+
+    /**
+    @brief
+        The PickupCarrier interface provides the means, for any class implementing it, to possess Pickupables.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _OrxonoxExport PickupCarrier : virtual public OrxonoxClass
+    {
+        friend class Pickupable; //!< The Pickupable has full acces to its PickupCarrier.
+        //TODO: Ugly workaround.
+        friend class Pickup;
+        friend class HealthPickup;
+        friend class MetaPickup;
+        
+        public:
+            PickupCarrier(); //!< Constructor.
+            virtual ~PickupCarrier(); //!< Destructor.
+            
+            /**
+            @brief Can be called to pick up a Pickupable.
+            @param pickup A pointer to the Pickupable.
+            @return Returns true if the Pickupable was picked up, false if not.
+            */
+            bool pickup(Pickupable* pickup)
+                {
+                    bool pickedUp = this->pickups_.insert(pickup).second;
+                    if(pickedUp)
+                    {
+                        COUT(4) << "Picked up Pickupable " << pickup->getIdentifier()->getName() << "(&" << pickup << ")." << std::endl;
+                        pickup->pickedUp(this);
+                    }
+                    return pickedUp;
+                }
+                
+            /**
+            @brief Can be called to drop a Pickupable.
+            @param pickup A pointer to the Pickupable.
+            @param drop If the Pickupable should just be removed from the PickupCarrier without further action, this can be set to false. true is default.
+            @return Returns true if the Pickupable has been dropped, false if not.
+            */
+            bool drop(Pickupable* pickup, bool drop = true)
+                { 
+                    bool dropped = this->pickups_.erase(pickup) == 1;
+                    if(dropped && drop)
+                    {
+                        COUT(4) << "Dropping Pickupable " << pickup->getIdentifier()->getName() << "(&" << pickup << ")." << std::endl;
+                        pickup->dropped();
+                    }
+                    return dropped;
+                }
+                
+            /**
+            @brief Can be used to check whether the PickupCarrier or a child of his is a target ot the input Pickupable.
+            @param pickup A pointer to the Pickupable.
+            @return Returns true if the PickupCarrier or one of its children is a target, false if not.
+            */
+            //TODO: Use?
+            bool isTarget(const Pickupable* pickup)
+                {
+                    if(pickup->isTarget(this)) //!< If the PickupCarrier itself is a target.
+                        return true;
+                    
+                    //! Go recursively through all children to check whether they are a target.
+                    std::list<PickupCarrier*>* children = this->getCarrierChildren();
+                    for(std::list<PickupCarrier*>::const_iterator it = children->begin(); it != children->end(); it++)
+                    {
+                        if((*it)->isTarget(pickup))
+                            return true;
+                    }
+                    
+                    children->clear();
+                    delete children;
+                    
+                    return false;
+                }
+                
+            /**
+            @brief Get the carrier that is both a child of the PickupCarrier (or the PickupCarrier itself) and a target of the input Pickupable.
+            @param pickup A pounter to the Pickupable.
+            @return Returns a pointer to the PickupCarrier that is the target of the input Pickupable.
+            */
+            PickupCarrier* getTarget(const Pickupable* pickup)
+                {
+                    if(!this->isTarget(pickup))
+                        return NULL;
+                    
+                    if(pickup->isTarget(this)) //!< If the PickupCarrier itself is a target.
+                        return this;
+                    
+                    //! Go recursively through all children to check whether they are the target.
+                    std::list<PickupCarrier*>* children = this->getCarrierChildren();
+                    for(std::list<PickupCarrier*>::iterator it = children->begin(); it != children->end(); it++)
+                    {
+                        if(pickup->isTarget(*it))
+                            return *it;
+                    }
+                    
+                    children->clear();
+                    delete children;
+                    
+                    return NULL;
+                }
+            
+        protected:        
+            /**
+            @brief Get all direct children of this PickupSpawner.
+                   This method needs to be implemented by any direct derivative class of PickupCarrier.
+            @return Returns a pointer to a list of all direct children. 
+            */
+            //TODO: Good return type? Maybe not const and destroyed in isTarget...
+            virtual std::list<PickupCarrier*>* getCarrierChildren(void) = 0;
+            /**
+            @brief Get the parent of this PickupSpawner
+                   This method needs to be implemented by any direct derivative class of PickupCarrier.
+            @return Returns a pointer to the parent.
+            */
+            virtual PickupCarrier* getCarrierParent(void) = 0;
+            /**
+            @brief Get the (absolute) position of the PickupCarrier.
+                   This method needs to be implemented by any direct derivative class of PickupCarrier.
+            @return Returns the position as a Vector3.
+            */
+            virtual const Vector3& getCarrierPosition(void) = 0;
+                            
+            /**
+            @brief Get all Pickupables this PickupCarrier has.
+            @return  Returns the set of all Pickupables this PickupCarrier has.
+            */
+            std::set<Pickupable*>& getPickups(void)
+                { return this->pickups_; }
+        
+        private:
+            std::set<Pickupable*> pickups_; //!< The list of Pickupables carried by this PickupCarrier.
+            
+    };
+}
+
+#endif /* _PickupCarrier_H__ */
Index: code/trunk/src/orxonox/interfaces/Pickupable.cc
===================================================================
--- code/trunk/src/orxonox/interfaces/Pickupable.cc	(revision 6524)
+++ code/trunk/src/orxonox/interfaces/Pickupable.cc	(revision 6524)
@@ -0,0 +1,275 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 2
+ *   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, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the Pickupable class.
+*/
+
+#include "Pickupable.h"
+
+#include "core/Identifier.h"
+#include "core/CoreIncludes.h"
+#include "pickup/PickupIdentifier.h"
+#include "PickupCarrier.h"
+
+namespace orxonox
+{
+    
+    /**
+    @brief
+        Constructor. Registers the objects and initializes its member variables.
+    */
+    Pickupable::Pickupable()
+    {
+        this->used_ = false;
+        this->pickedUp_ = false;
+        
+        RegisterRootObject(Pickupable);
+        
+        this->carrier_ = NULL;
+        
+        this->pickupIdentifier_ = new PickupIdentifier(this);
+    }
+    
+    /**
+    @brief
+        Destructor. 
+    */
+    Pickupable::~Pickupable()
+    {
+        if(this->isUsed())
+            this->setUsed(false);
+        
+        if(this->isPickedUp() && this->getCarrier() != NULL)
+        {
+            this->getCarrier()->drop(this, false);
+            this->setCarrier(NULL);
+        }
+    }
+    
+    /**
+    @brief
+        Sets the Pickupable to used or unused, depending on the input.
+    @param used
+        If used is true the Pickupable is set to used, it is set to unused, otherwise.
+    @return
+        Returns true if the used state was changed, false if not.
+    */
+    bool Pickupable::setUsed(bool used)
+    {
+        if(this->used_ == used)
+            return false;
+        
+        COUT(4) << "Pickupable (&" << this << ") set to used " << used << "." << std::endl;
+        
+        this->used_ = used;
+        this->changedUsed();
+        return true;
+    }
+    
+    /**
+    @brief
+        Get whether the given PickupCarrier is a target of this pickup.
+    @param carrier
+        The PickupCarrier of which it has to be determinde whether it is a target of this pickup.
+    @return
+        Returns true if the given PickupCarrier is a target.
+    */
+    bool Pickupable::isTarget(const PickupCarrier* carrier) const
+    {
+        return this->isTarget(carrier->getIdentifier());
+    }
+    
+    /**
+    @brief
+        Get whether a given class, represented by the input Identifier, is a target of this pickup.
+    @param target
+        The Identifier of which it has to be determinde whether it is a target of this pickup.
+    @return
+        Returns true if the given Identifier is a target.
+    */
+    bool Pickupable::isTarget(Identifier* target) const
+    {
+        //! Iterate through all targets of this Pickupable.
+        for(std::list<Identifier*>::const_iterator it = this->targets_.begin(); it != this->targets_.end(); it++)
+        {
+            if(target->isA(*it))
+                return true;
+        }
+        return false;
+    }
+        
+    /**
+    @brief
+        Add a PickupCarrier as target of this pickup.
+    @param target
+        The PickupCarrier to be added.
+    @return
+        Returns true if the target was added, false if not.
+    */
+    bool Pickupable::addTarget(PickupCarrier* target)
+    {
+        return this->addTarget(target->getIdentifier());
+    }
+    
+    /**
+    @brief
+        Add a class, representetd by the input Identifier, as target of this pickup.
+    @param target
+        The Identifier to be added.
+    @return
+        Returns true if the target was added, false if not.
+    */
+    bool Pickupable::addTarget(Identifier* target)
+    {
+        if(this->isTarget(target)) //!< If the input target is already present in the list of targets.
+            return false;
+        
+        COUT(4) << "Target " << target->getName() << " added to Pickupable (&" << this << ")." << std::endl;
+        this->targets_.push_back(target);
+        return true;
+    }
+    
+    /**
+    @brief  
+        Sets the Pickupable to picked up.
+        This method will be called by the PickupCarrier picking the Pickupable up.
+    @param carrier
+        The PickupCarrier that picked the Pickupable up.
+    @return
+        Returns false if, for some reason, the pickup could not be picked up, e.g. it was picked up already.
+    */
+    bool Pickupable::pickedUp(PickupCarrier* carrier)
+    {
+        if(this->isPickedUp()) //!< If the Pickupable is already picked up.
+            return false;
+        
+        COUT(4) << "Pickupable (&" << this << ") got picked up by a PickupCarrier (&" << carrier << ")." << std::endl;
+        this->setCarrier(carrier);
+        this->setPickedUp(true);
+        return true;
+    }
+    
+    /**
+    @brief
+        Helper method to set the Pickupable to either picked up or not picked up.
+    @param pickedUp
+        The value this->pickedUp_ should be set to.
+    @return
+        Returns true if the pickedUp status was changed, false if not.
+    */
+    bool Pickupable::setPickedUp(bool pickedUp)
+    {
+        if(this->pickedUp_ == pickedUp)
+            return false;
+        
+        COUT(4) << "Pickupable (&" << this << ") set to pickedUp " << pickedUp << "." << std::endl;
+        
+        this->pickedUp_ = pickedUp;
+        this->changedPickedUp();
+        return true;
+    }
+        
+    /**
+    @brief
+        Sets the carrier of the pickup.
+    @param carrier
+        Sets the input PickupCarrier as the carrier of the pickup.
+    */
+    inline bool Pickupable::setCarrier(PickupCarrier* carrier)
+    {
+        if(this->carrier_ == carrier)
+            return false;
+        
+        COUT(4) << "Pickupable (&" << this << ") changed Carrier (& " << carrier << ")." << std::endl;
+        
+        this->carrier_ = carrier;
+        this->changedCarrier();
+        return true;
+    }
+    
+    /**
+    @brief 
+        Sets the Pickupable to not picked up or dropped.
+        This method will be called by the PickupCarrier dropping the Pickupable.
+    @return
+        Returns false if the pickup could not be dropped.
+    */
+    bool Pickupable::dropped(void)
+    {
+        if(!this->isPickedUp()) //!< If the Pickupable is not picked up.
+            return false;
+        
+        COUT(4) << "Pickupable (&" << this << ") got dropped up by a PickupCarrier (&" << this->getCarrier() << ")." << std::endl;
+        this->setUsed(false);
+        this->setPickedUp(false);
+        
+        bool created = this->createSpawner(this->getCarrier()->getCarrierPosition());
+        
+        this->setCarrier(NULL);
+        //TODO: possible problem.
+        if(!created)
+        {
+            this->destroy();
+        }
+        
+        return true;
+    }
+    
+    /**
+    @brief
+        Creates a duplicate of the Pickupable.
+    @return
+        Returns the clone of this pickup as a pointer to a Pickupable.
+    */
+    Pickupable* Pickupable::clone(void)
+    {
+        OrxonoxClass* item = NULL;
+        this->clone(item);
+        
+        Pickupable* pickup = dynamic_cast<Pickupable*>(item);
+        
+        COUT(4) << "Pickupable (&" << this << ") cloned. Clone is new Pickupable (&" << pickup << ")." << std::endl;
+        return pickup;
+    }
+    
+    /**
+    @brief
+        Creates a duplicate of the input OrxonoxClass.
+        This method needs to be implemented by any Class inheriting from Pickupable.
+    @param item
+        A pointer to the OrxonoxClass that is to be duplicated.
+    */
+    //TODO: Specify how the implementation must be done in detail.
+    void Pickupable::clone(OrxonoxClass*& item)
+    {
+        SUPER(Pickupable, clone, item);
+    }
+    
+}
Index: code/trunk/src/orxonox/interfaces/Pickupable.h
===================================================================
--- code/trunk/src/orxonox/interfaces/Pickupable.h	(revision 6524)
+++ code/trunk/src/orxonox/interfaces/Pickupable.h	(revision 6524)
@@ -0,0 +1,158 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 2
+ *   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, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the Pickupable class.
+*/
+
+#ifndef _Pickupable_H__
+#define _Pickupable_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include "core/Super.h"
+
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    
+    /**
+    @brief
+        An Interface (or more precisely an abstract class) to model and represent different (all kinds of) pickups.
+    @author
+        Damian 'Mozork' Frick
+    */
+    //TODO: Add stuff like weight/space ?
+    class _OrxonoxExport Pickupable : virtual public OrxonoxClass
+    {
+        
+        public:
+            Pickupable(); //!< Default constructor.
+            virtual ~Pickupable(); //!< Default destructor.
+            
+            /**
+            @brief Get whether the pickup is currently in use or not.
+            @return Returns true if the pickup is currently in use.
+            */
+            inline bool isUsed(void)
+                { return this->used_; }
+            /**
+            @brief  Should be called when the pickup has transited from used to unused or the other way around.
+                    Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedUsed); to their changdeUsed method.
+            */
+            virtual void changedUsed(void) {}
+            
+            /**
+            @brief Get the carrier of the pickup.
+            @return Returns a pointer to the carrier of the pickup.
+            */
+            inline PickupCarrier* getCarrier(void)
+                { return this->carrier_; }
+            /**
+            @brief Should be called when the pickup has changed its PickupCarrier.
+                   Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedCarrier); to their changedCarrier method.
+            */
+            virtual void changedCarrier(void) {}
+            
+            /**
+            @brief Returns whether the Pickupable is currently picked up.
+            @return Returns true if the Pickupable is currently picked up, false if not.
+            */
+            inline bool isPickedUp(void)
+                { return this->pickedUp_; }
+            /**
+            @brief  Should be called when the pickup has transited from picked up to dropped or the other way around.
+                    Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedPickedUp); to their changedPickedUp method.
+            */
+            virtual void changedPickedUp(void) {}
+            
+            //TODO: Better private, or protected?
+            bool pickedUp(PickupCarrier* carrier); //!< Sets the Pickupable to picked up.
+            bool dropped(void); //!< Sets the Pickupable to not picked up or dropped.
+            
+            bool isTarget(const PickupCarrier* carrier) const; //!< Get whether the given PickupCarrier is a target of this pickup.
+            virtual bool isTarget(Identifier* identifier) const; //!< Get whether a given class, represented by the input Identifier, is a target of this pickup.
+            bool addTarget(PickupCarrier* target); //!< Add a PickupCarrier as target of this pickup.
+            bool addTarget(Identifier* identifier); //!< Add a class, representetd by the input Identifier, as target of this pickup.
+            
+            Pickupable* clone(void); //!< Creates a duplicate of the Pickupable.
+            virtual void clone(OrxonoxClass*& item); //!< Creates a duplicate of the input OrxonoxClass.
+            
+            /**
+            @brief Get the PickupIdentifier of this Pickupable.
+            @return Returns a pointer to the PickupIdentifier of this Pickupable.
+            */
+            virtual const PickupIdentifier* getPickupIdentifier(void)
+                { return this->pickupIdentifier_; }
+                
+            virtual void destroy(void)
+                { delete this; }
+                
+            //TODO: Make them work as protected.
+            bool setUsed(bool used); //!< Sets the Pickupable to used or unused, depending on the input.
+            bool setPickedUp(bool pickedUp); //!< Helper method to set the Pickupable to either picked up or not picked up.
+            bool setCarrier(PickupCarrier* carrier); //!< Sets the carrier of the pickup.
+            
+        protected:
+            /**
+            @brief Helper method to initialize the PickupIdentifier.
+            */
+            //TODO: Really needed?
+            void initializeIdentifier(void) {}
+            
+            /**
+            @brief Facilitates the creation of a PickupSpawner upon dropping of the Pickupable.
+                   This method must be implemented by any class directly inheriting from Pickupable. It is most easily done by just creating a new DroppedPickup, e.g.:
+                   DroppedPickup(BaseObject* creator, Pickupable* pickup, const Vector3& position, float triggerDistance);
+            @param position The position at which the PickupSpawner should be placed.
+            @return Returns true if a spawner was created, false if not.
+            */
+            virtual bool createSpawner(const Vector3& position) = 0;
+            
+            //TODO: Move to private and create get method in protected.
+            PickupIdentifier* pickupIdentifier_; //!< The PickupIdentifier of this Pickupable.
+            
+        private:
+            
+            bool used_; //!< Whether the pickup is currently in use or not.
+            bool pickedUp_; //!< Whether the pickup is currently picked up or not.
+            
+            PickupCarrier* carrier_; //!< The carrier of the pickup.
+            std::list<Identifier*> targets_; //!< The possible targets of this pickup.
+
+    };
+    
+    SUPER_FUNCTION(10, Pickupable, changedUsed, false);
+    SUPER_FUNCTION(12, Pickupable, changedCarrier, false);
+    SUPER_FUNCTION(13, Pickupable, changedPickedUp, false);
+}
+
+#endif /* _Pickupable_H__ */
