Index: code/branches/pickup2/src/modules/pickup/PickupSpawner.cc
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/PickupSpawner.cc	(revision 5953)
+++ code/branches/pickup2/src/modules/pickup/PickupSpawner.cc	(revision 6405)
@@ -23,5 +23,5 @@
  *      Daniel 'Huty' Haggenmueller
  *   Co-authors:
- *      ...
+ *      Damian 'Mozork' Frick
  *
  */
@@ -34,12 +34,10 @@
 #include "PickupSpawner.h"
 
-#include "BaseItem.h"
-
 #include "core/CoreIncludes.h"
-#include "core/GUIManager.h"     // HACK; see below
+//#include "core/GUIManager.h"     // HACK; see below
 #include "core/Template.h"
 #include "core/XMLPort.h"
 #include "worldentities/pawns/Pawn.h"
-#include "PickupInventory.h"    // HACK; Only for hack, remove later
+//#include "PickupInventory.h"    // HACK; Only for hack, remove later
 
 
@@ -47,7 +45,7 @@
 {
 
-    const float PickupSpawner::bounceSpeed_s = 6.0f;
-    const float PickupSpawner::rotationSpeed_s = 1.0f;
-    const float PickupSpawner::bounceDistance_s = 4.0f;
+//     const float PickupSpawner::bounceSpeed_s = 6.0f;
+//     const float PickupSpawner::rotationSpeed_s = 1.0f;
+//     const float PickupSpawner::bounceDistance_s = 4.0f;
 
     CreateFactory(PickupSpawner);
@@ -64,11 +62,9 @@
     }
 
-    PickupSpawner::PickupSpawner(BaseObject* creator, BaseItem* item, float triggerDistance, float respawnTime, int maxSpawnedItems) : StaticEntity(creator)
+    PickupSpawner::PickupSpawner(BaseObject* creator, Pickupable* pickup, 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->pickup_ = pickup;
 
         this->triggerDistance_ = triggerDistance;
@@ -81,8 +77,9 @@
         RegisterObject(PickupSpawner);
 
-        this->itemTemplate_ = NULL;
+        this->pickup_ = NULL;
+        
         this->triggerDistance_ = 20;
-        this->respawnTime_ = 0.0f;
-        this->tickSum_ = 0.0f;
+        this->respawnTime_ = 0;
+        this->tickSum_ = 0;
         this->maxSpawnedItems_ = INF;
         this->spawnsRemaining_ = INF;
@@ -110,5 +107,6 @@
         SUPER(PickupSpawner, XMLPort, xmlelement, mode);
 
-        XMLPortParam(PickupSpawner, "item", setItemTemplateName, getItemTemplateName, xmlelement, mode);
+        XMLPortObject(PickupSpawner, Pickupable, "pickup", addPickupable, getPickupable, xmlelement, mode);
+        
         XMLPortParam(PickupSpawner, "triggerDistance", setTriggerDistance, getTriggerDistance, xmlelement, mode);
         XMLPortParam(PickupSpawner, "respawnTime", setRespawnTime, getRespawnTime, xmlelement, mode);
@@ -119,18 +117,39 @@
         // Load the GUI image as soon as the PickupSpawner gets loaded
         //  = less delays while running
-        BaseObject* newObject = this->itemTemplate_->getBaseclassIdentifier()->fabricate(this);
-        BaseItem* asItem = orxonox_cast<BaseItem*>(newObject);
-        if (asItem)
-        {
-            asItem->addTemplate(this->itemTemplate_);
-            PickupInventory::getImageForItem(asItem);
-            newObject->destroy();
-        }
+//         BaseObject* newObject = this->itemTemplate_->getBaseclassIdentifier()->fabricate(this);
+//         BaseItem* asItem = orxonox_cast<BaseItem*>(newObject);
+//         if (asItem)
+//         {
+//             asItem->addTemplate(this->itemTemplate_);
+//             PickupInventory::getImageForItem(asItem);
+//             newObject->destroy();
+//         }
 
         //  & load the GUI itself too, along with some empty windows
         //   = even less delays
-        GUIManager::getInstance().showGUI("PickupInventory");
-        GUIManager::getInstance().executeCode("hideGUI(\"PickupInventory\")");
-        PickupInventory::getSingleton();
+//         GUIManager::getInstance().showGUI("PickupInventory");
+//         GUIManager::getInstance().executeCode("hideGUI(\"PickupInventory\")");
+//         PickupInventory::getSingleton();
+    }
+    
+    void PickupSpawner::addPickupable(Pickupable* pickup)
+    {
+        if(this->pickup_ != NULL)
+        {
+            COUT(1) << "addPickupable called, with this->pickup_ already set." << std::endl;
+            return;
+        }
+        if(pickup == NULL)
+        {
+            COUT(1) << "Argument of addPickupable is NULL." << std::endl;
+            return;
+        }
+        
+        this->pickup_ = pickup;
+    }
+    
+    Pickupable* PickupSpawner::getPickupable(void)
+    {
+        return this->pickup_;
     }
 
@@ -139,23 +158,11 @@
         Invoked when the activity has changed. Sets visibility of attached objects.
     */
-    void PickupSpawner::changedActivity()
-    {
-        SUPER(PickupSpawner, changedActivity);
-
-        for (std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin(); it != this->getAttachedObjects().end(); it++)
-            (*it)->setVisible(this->isActive());
-    }
-
-    /**
-    @brief
-        Set the template name of the item to spawn, also loads the template.
-    @param name
-        Name of the new template.
-    */
-    void PickupSpawner::setItemTemplateName(const std::string& name)
-    {
-        this->itemTemplateName_ = name;
-        this->itemTemplate_ = Template::getTemplate(name);
-    }
+//     void PickupSpawner::changedActivity()
+//     {
+//         SUPER(PickupSpawner, changedActivity);
+// 
+//         for (std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin(); it != this->getAttachedObjects().end(); it++)
+//             (*it)->setVisible(this->isActive());
+//     }
 
     void PickupSpawner::setMaxSpawnedItems(int items)
@@ -171,23 +178,27 @@
         Time since last tick.
     */
-    //TODO: Replace this with a real DistanceTrigger.
+    //TODO: Replace this with a real DistanceTrigger?
     void PickupSpawner::tick(float dt)
     {
+        //! If the PickupSpawner is active.
         if (this->isActive())
         {
-            //! Triggers as soon as a Pawn is in the specified distance.
+            //! Iterate trough all Pawns.
             for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
             {
                 Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
-                if (distance.length() < this->triggerDistance_)
+                //! If a Pawn, that fits the target-range of the item spawned by this Pickup, is in trigger-distance.
+                if (distance.length() < this->triggerDistance_ && this->pickup_->isTarget(*it))
+                {
                     this->trigger(*it);
+                }
             }
 
             //! Animation.
-            this->yaw(Radian(rotationSpeed_s*dt));
-            this->tickSum_ += bounceSpeed_s*dt;
-            this->translate(Vector3(0,bounceDistance_s*dt*sin(this->tickSum_),0));
-            if (this->tickSum_ > 2*Ogre::Math::PI)
-                this->tickSum_ -= 2*Ogre::Math::PI;
+//             this->yaw(Radian(rotationSpeed_s*dt));
+//             this->tickSum_ += bounceSpeed_s*dt;
+//             this->translate(Vector3(0,bounceDistance_s*dt*sin(this->tickSum_),0));
+//             if (this->tickSum_ > 2*Ogre::Math::PI)
+//                 this->tickSum_ -= 2*Ogre::Math::PI;
         }
     }
@@ -205,55 +216,69 @@
     void PickupSpawner::trigger(Pawn* pawn)
     {
-        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.
+        //TODO: If private, isActive doesn't need to be tested anymore.
+        if (this->isActive()) //!< Checks whether PickupItem is active.
+        {
+            Pickupable* pickup = this->getPickup();
+            if (pickup != NULL) //!< If everything went ok, and pickup is not NULL.
             {
-                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->spawnsRemaining_ != INF)
-                    {
-                        this->spawnsRemaining_--;
-                    }
-
-                    if (this->spawnsRemaining_ != 0 && this->respawnTime_ > 0.0f)
-                    {
-                        this->respawnTimer_.setTimer(this->respawnTime_, false, createExecutor(createFunctor(&PickupSpawner::respawnTimerCallback, this)));
-
-                        this->setActive(false);
-                        this->fireEvent();
-                    }
+                PickupCarrier* carrier = dynamic_cast<PickupCarrier*>(pawn);
+                if(carrier == NULL)
+                {
+                    COUT(1) << "This is bad. Pawn isn't PickupCarrier." << std::endl;
+                    return;
+                }
+                
+                if(pickup->pickup(carrier))
+                {
+                    COUT(3) << "Pickup got picked up." << std::endl;
+
+                    this->decrementSpawnsRemaining();
                 }
                 else
                 {
-                    item->destroy();
+                    pickup->destroy();
                 }
             }
         }
-
-        if(this->spawnsRemaining_ == 0)
+    }
+    
+    void PickupSpawner::decrementSpawnsRemaining(void)
+    {
+        if(this->spawnsRemaining_ != INF)
+        {
+            this->spawnsRemaining_--;
+        }
+        if(this->spawnsRemaining_ != 0 && this->respawnTime_ > 0)
+        {
+            //TODO: Nicer?
+            this->respawnTimer_.setTimer(this->respawnTime_, false, createExecutor(createFunctor(&PickupSpawner::respawnTimerCallback, this)));
+
+            this->setActive(false);
+            this->fireEvent();
+        }
+        else
         {
             COUT(3) << "PickupSpawner empty, selfdistruct initialized." << std::endl;
             this->setActive(false);
-            this->destroy();
-        }
-    }
-
-    /**
-    @brief
-        Creates a BaseItem of the type specified by the PickupSpawner.
+            this->destroy(); //TODO: Implement destroy().
+        }
+    }
+
+    /**
+    @brief
+        Creates a new Pickupable.
     @return
-        The BaseItem created.
+        The Pickupable created.
     */    
-    BaseItem* PickupSpawner::getItem(void)
-    {
-        BaseObject* newItem = this->itemTemplate_->getBaseclassIdentifier()->fabricate(this); //!< Creates new object of specified item type.
-        return orxonox_cast<BaseItem*>(newItem);
+    Pickupable* PickupSpawner::getPickup(void)
+    {
+        if(this->spawnsRemaining_ == 0)
+        {
+            COUT(1) << "Massive Error: PickupSpawner still alive until having spawned last item." << std::endl;
+            return NULL;
+        }
+        
+        Pickupable* pickup = this->pickup_->clone();
+        return pickup;
     }
 
