Index: code/branches/pickup2/src/orxonox/pickup/DroppedItem.cc
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/DroppedItem.cc	(revision 5947)
+++ code/branches/pickup2/src/orxonox/pickup/DroppedItem.cc	(revision 5953)
@@ -39,5 +39,5 @@
 namespace orxonox
 {
-    CreateFactory(DroppedItem);
+    CreateFactory(DroppedItem); //TODO: This isn't needed, is it?
 
     /**
@@ -45,11 +45,13 @@
         Constructor. Registers object and sets default values.
     */
-    DroppedItem::DroppedItem(BaseObject* creator) : StaticEntity(creator)
+    DroppedItem::DroppedItem(BaseObject* creator) : PickupSpawner(creator)
     {
         RegisterObject(DroppedItem);
+    }
 
-        this->triggerDistance_ = 20.0f;
-        this->timeToLive_ = 0;
-        this->item_ = NULL;
+    DroppedItem::DroppedItem(BaseObject* creator, BaseItem* item, float triggerDistance, float respawnTime, int maxSpawnedItems) : PickupSpawner(creator, item, triggerDistance, respawnTime, maxSpawnedItems)
+    {
+        RegisterObject(DroppedItem);
+        this->item_ = item;
     }
 
@@ -58,5 +60,4 @@
         Default destructor.
     */
-    //TODO: Destroy something?
     DroppedItem::~DroppedItem()
     {
@@ -64,66 +65,7 @@
     }
 
-    /**
-    @brief
-        Checks whether any pawn is in triggerDistance of the Item and calls this->trigger if so.
-    @param dt
-        The  duration of the last time interval.    
-    */
-    //TODO: Replace this with a DistanceTrigger!
-    void DroppedItem::tick(float dt)
+    BaseItem* DroppedItem::getItem(void)
     {
-        if (this->item_)
-        {
-            for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it) //!< Iterate through all Pawns.
-            {
-                Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
-                if (distance.length() < this->triggerDistance_)
-                    this->trigger(*it);
-            }
-        }
-    }
-
-    /**
-    @brief
-        Called when the DroppedItem is triggered. Adds the item to the triggering pawn.
-    */
-    void DroppedItem::trigger(Pawn* pawn)
-    {
-        if (this->item_->pickedUp(pawn)) //If pickup was successful.
-        {
-            COUT(3) << "DroppedItem '" << this->item_->getPickupIdentifier() << "' picked up." << std::endl;
-            this->destroy();
-        }
-    }
-
-    /**
-    @brief
-        Creates a timer to call this->timerCallback() at expiration of timeToLive.
-    */
-    //TODO: Better Comments.
-    void DroppedItem::createTimer()
-    {
-        if (this->timeToLive_ > 0)
-        {
-            this->timer_.setTimer(this->timeToLive_, false, createExecutor(createFunctor(&DroppedItem::timerCallback, this)), false);
-        }
-    }
-    
-    /**
-    @brief
-        Destroys the item. Called by the set timer upon its expiration.
-    */
-    //TODO: Choose better function name if this doesn't create dependency inconsistencies. e.g. this->destroy() or this->timeOut()
-    //Make certain that only one pawn has the same item, because if not, deliting the item would lead to a possible segfault.
-    //If the item is destroyed here, shouldn't it be destroyed in the destructor as well?
-    void DroppedItem::timerCallback()
-    {
-        if (this->item_)
-        {
-            COUT(3) << "Delete DroppedItem with '" << this->item_->getPickupIdentifier() << "'" << std::endl;
-            this->item_->destroy();
-        }
-
-        this->destroy();
+        return this->item_;
     }
 
@@ -133,13 +75,12 @@
     */
     //TODO: Comment.
-    //This is for pawns dropping items they have...
-    //Probably better to create a spawner with only 1 item in it.
-    //Various different thigs are done here, which in my opinion should eighter be done in XML or some where else, preferably in XML.
     //Each pickup should have a XML template where the Model and Billboard, and so on, is specified.
-    //The position, item and timetoLive should be specified by this Classes XMLPort function.
-    //These adjustments above, will very likely create inkonsistencies in the level files, possibly templates.
     /*static*/ DroppedItem* DroppedItem::createDefaultDrop(BaseItem* item, const Vector3& position, const ColourValue& flareColour, float timeToLive)
     {
-        DroppedItem* drop = new DroppedItem(item);
+        //TODO: triggerDistance?
+        float triggerDistance = 20.0;
+        DroppedItem* droppedItem = new DroppedItem(item, item, triggerDistance, 0, 1);
+        
+        //TODO: Do this somehwere else?
         Model* model = new Model(item);
         Billboard* billboard = new Billboard(item);
@@ -152,16 +93,11 @@
         billboard->setScale(0.5f);
 
-        drop->setPosition(position);
-        drop->attach(model);
-        drop->attach(billboard);
-
-        drop->setItem(item);
-
-        drop->setTimeToLive(timeToLive);
-        drop->createTimer();
+        droppedItem->setPosition(position);
+        droppedItem->attach(model);
+        droppedItem->attach(billboard);
 
         COUT(3) << "Created DroppedItem for '" << item->getPickupIdentifier() << "' at (" << position.x << "," << position.y << "," << position.z << ")." << std::endl;
 
-        return drop;
+        return droppedItem;
     }
 
Index: code/branches/pickup2/src/orxonox/pickup/DroppedItem.h
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/DroppedItem.h	(revision 5947)
+++ code/branches/pickup2/src/orxonox/pickup/DroppedItem.h	(revision 5953)
@@ -37,54 +37,25 @@
 #include "OrxonoxPrereqs.h"
 
-#include "tools/Timer.h"
-#include "tools/interfaces/Tickable.h"
-#include "worldentities/StaticEntity.h"
+#include "PickupSpawner.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport DroppedItem : public StaticEntity, public Tickable
+    class _OrxonoxExport DroppedItem : public PickupSpawner
     {
-    public:
-        DroppedItem(BaseObject* creator);
-        virtual ~DroppedItem();
+        public:
+            DroppedItem(BaseObject* creator);
+            DroppedItem(BaseObject* creator, BaseItem* item, float triggerDistance, float respawnTime, int maxSpawnedItems);
+            virtual ~DroppedItem();
 
-        //TODO: Comment.
-        //DroppedItem -> Item with no owner, alone in space?
-        //Would be much nicer if it would be triggered by a standard issue DistanceTrigger.
-        //Where is this created? I see no XMLPort.
-        //Where is the item for this created? What happens if more than one pawn triggers this?
-        //Add more than just one items, or even better create the ability to add a Collection.? Rename to ...?
+            static DroppedItem* createDefaultDrop(BaseItem* item, const Vector3& position, const ColourValue& flareColour = ColourValue(0.5f, 1.0f, 0.3f), float timeToLive = 0);
+            static DroppedItem* createDefaultDrop(BaseItem* item, Pawn* pawn, const ColourValue& flareColour = ColourValue(0.5f, 1.0f, 0.3f), float timeToLive = 0);
 
-        void tick(float dt);
-        void trigger(Pawn* pawn);
+        protected:
+            virtual BaseItem* getItem(void);
 
-        static DroppedItem* createDefaultDrop(BaseItem* item, const Vector3& position, const ColourValue& flareColour = ColourValue(0.5f, 1.0f, 0.3f), float timeToLive = 0);
-        static DroppedItem* createDefaultDrop(BaseItem* item, Pawn* pawn, const ColourValue& flareColour = ColourValue(0.5f, 1.0f, 0.3f), float timeToLive = 0);
+        private:
 
-        void createTimer(); //TODO: Can this be made private, too?
-        void timerCallback(); //TODO: This should really be private.
+            BaseItem* item_; //!< The dropped item.
 
-        inline float getTriggerDistance() const
-            { return this->triggerDistance_; }
-        inline void setTriggerDistance(float distance)
-            { this->triggerDistance_ = distance; }
-
-        inline BaseItem* getItem() const
-            { return this->item_; }
-        //TODO: Needs to be public?
-        inline void setItem(BaseItem* item)
-            { this->item_ = item; }
-
-        inline float getTimeToLive() const
-            { return this->timeToLive_; }
-        //TODO: Needs to be public?
-        inline void setTimeToLive(float time)
-            { this->timeToLive_ = time; }
-    private:
-        float timeToLive_;
-        float triggerDistance_;
-        BaseItem* item_;
-
-        Timer timer_;
     };
 }
Index: code/branches/pickup2/src/orxonox/pickup/PickupSpawner.cc
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/PickupSpawner.cc	(revision 5947)
+++ code/branches/pickup2/src/orxonox/pickup/PickupSpawner.cc	(revision 5953)
@@ -46,4 +46,5 @@
 namespace orxonox
 {
+
     const float PickupSpawner::bounceSpeed_s = 6.0f;
     const float PickupSpawner::rotationSpeed_s = 1.0f;
@@ -60,10 +61,30 @@
     PickupSpawner::PickupSpawner(BaseObject* creator) : StaticEntity(creator)
     {
+        this->initialize();
+    }
+
+    PickupSpawner::PickupSpawner(BaseObject* creator, BaseItem* item, float triggerDistance, float respawnTime, int maxSpawnedItems) : StaticEntity(creator)
+    {
+        this->initialize();
+  
+        //TODO: Does this actually work?
+        this->itemTemplateName_ = item->getIdentifier()->getName();
+        this->itemTemplate_ = Template::getTemplate(this->itemTemplateName_);
+
+        this->triggerDistance_ = triggerDistance;
+        this->respawnTime_ = respawnTime;
+        this->setMaxSpawnedItems(maxSpawnedItems);
+    }
+
+    void PickupSpawner::initialize(void)
+    {
         RegisterObject(PickupSpawner);
 
-        this->itemTemplate_ = 0;
+        this->itemTemplate_ = NULL;
         this->triggerDistance_ = 20;
         this->respawnTime_ = 0.0f;
         this->tickSum_ = 0.0f;
+        this->maxSpawnedItems_ = INF;
+        this->spawnsRemaining_ = INF;
     }
 
@@ -92,4 +113,5 @@
         XMLPortParam(PickupSpawner, "triggerDistance", setTriggerDistance, getTriggerDistance, xmlelement, mode);
         XMLPortParam(PickupSpawner, "respawnTime", setRespawnTime, getRespawnTime, xmlelement, mode);
+        XMLPortParam(PickupSpawner, "maxSpawnedItems", setMaxSpawnedItems, getMaxSpawnedItems, xmlelement, mode);
 
         //TODO: Kill hack.
@@ -137,4 +159,10 @@
     }
 
+    void PickupSpawner::setMaxSpawnedItems(int items)
+    {
+        this->maxSpawnedItems_ = items;
+        this->spawnsRemaining_ = items;
+    }
+
     /**
     @brief
@@ -148,4 +176,5 @@
         if (this->isActive())
         {
+            //! Triggers as soon as a Pawn is in the specified distance.
             for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
             {
@@ -154,4 +183,6 @@
                     this->trigger(*it);
             }
+
+            //! Animation.
             this->yaw(Radian(rotationSpeed_s*dt));
             this->tickSum_ += bounceSpeed_s*dt;
@@ -174,18 +205,23 @@
     void PickupSpawner::trigger(Pawn* pawn)
     {
-        if (this->isActive() && this->itemTemplate_ && this->itemTemplate_->getBaseclassIdentifier())
-        {
-            BaseObject* newObject = this->itemTemplate_->getBaseclassIdentifier()->fabricate(this);
-            BaseItem* asItem = orxonox_cast<BaseItem*>(newObject);
-            if (asItem)
+        if (this->isActive() && this->itemTemplate_ && this->itemTemplate_->getBaseclassIdentifier()) //!< Checks whether PickupItem is active, amongst other things.
+        {
+            BaseItem* item = this->getItem();
+            if (item != NULL) //!< If the conversion was successful.
             {
-                asItem->setPickupIdentifier(this->itemTemplateName_);
-                asItem->addTemplate(this->itemTemplate_);
-
-                if (asItem->pickedUp(pawn))
+                item->setPickupIdentifier(this->itemTemplateName_); //TODO: Needed?
+                item->addTemplate(this->itemTemplate_); //TODO: Does what?
+
+                if(item->pickedUp(pawn))
                 {
                     COUT(3) << this->itemTemplateName_ << " got picked up." << std::endl;
 
-                    if (this->respawnTime_ > 0.0f)
+
+                    if(this->spawnsRemaining_ != INF)
+                    {
+                        this->spawnsRemaining_--;
+                    }
+
+                    if (this->spawnsRemaining_ != 0 && this->respawnTime_ > 0.0f)
                     {
                         this->respawnTimer_.setTimer(this->respawnTime_, false, createExecutor(createFunctor(&PickupSpawner::respawnTimerCallback, this)));
@@ -196,7 +232,28 @@
                 }
                 else
-                    newObject->destroy();
+                {
+                    item->destroy();
+                }
             }
         }
+
+        if(this->spawnsRemaining_ == 0)
+        {
+            COUT(3) << "PickupSpawner empty, selfdistruct initialized." << std::endl;
+            this->setActive(false);
+            this->destroy();
+        }
+    }
+
+    /**
+    @brief
+        Creates a BaseItem of the type specified by the PickupSpawner.
+    @return
+        The BaseItem created.
+    */    
+    BaseItem* PickupSpawner::getItem(void)
+    {
+        BaseObject* newItem = this->itemTemplate_->getBaseclassIdentifier()->fabricate(this); //!< Creates new object of specified item type.
+        return orxonox_cast<BaseItem*>(newItem);
     }
 
Index: code/branches/pickup2/src/orxonox/pickup/PickupSpawner.h
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/PickupSpawner.h	(revision 5947)
+++ code/branches/pickup2/src/orxonox/pickup/PickupSpawner.h	(revision 5953)
@@ -53,4 +53,5 @@
             //TODO: Add limit of items spawned here. Also possibility to spawn collections?
             PickupSpawner(BaseObject* creator);
+            PickupSpawner(BaseObject* creator, BaseItem* item, float triggerDistance, float respawnTime, int maxSpawnedItems);
             virtual ~PickupSpawner();
 
@@ -102,7 +103,21 @@
             inline void setRespawnTime(float time)
                 { this->respawnTime_ = time; }
+
+
+            inline int getMaxSpawnedItems(void)
+                { return this->maxSpawnedItems_; }
+            void setMaxSpawnedItems(int items);
+
+        protected:
+            virtual BaseItem* getItem(void);
+
         private:
+            void initialize(void);
+
             std::string itemTemplateName_;          //!< Template name of the item to spawn.
             Template* itemTemplate_;                //!< Template of the item to spawn.
+
+            int maxSpawnedItems_;                   //!< Maximum number of items spawned by this PickupSpawner.
+            int spawnsRemaining_;                   //!< Number of items that can be spawned by this PickupSpawner until it selfdestructs.
 
             float triggerDistance_;                 //!< Distance in which this gets triggered.
@@ -116,4 +131,6 @@
             float respawnTime_;                     //!< Time after which this gets re-actived.
             Timer respawnTimer_;                    //!< Timer used for re-activating.
+
+            static const int INF = -1;             //!< Constant for infinity.
     };
 }
