Index: code/branches/pickup3/src/modules/pickup/PickupSpawner.cc
===================================================================
--- code/branches/pickup3/src/modules/pickup/PickupSpawner.cc	(revision 6474)
+++ code/branches/pickup3/src/modules/pickup/PickupSpawner.cc	(revision 6475)
@@ -35,5 +35,4 @@
 
 #include "core/CoreIncludes.h"
-//#include "core/GUIManager.h"     // HACK; see below
 #include "core/Template.h"
 #include "core/XMLPort.h"
@@ -41,13 +40,7 @@
 #include "PickupManager.h"
 #include "PickupRepresentation.h"
-//#include "PickupInventory.h"    // HACK; Only for hack, remove later
-
 
 namespace orxonox
 {
-
-//     const float PickupSpawner::bounceSpeed_s = 6.0f;
-//     const float PickupSpawner::rotationSpeed_s = 1.0f;
-//     const float PickupSpawner::bounceDistance_s = 4.0f;
 
     CreateFactory(PickupSpawner);
@@ -64,7 +57,4 @@
         
         this->initialize();
-        
-        PickupRepresentation* representation = PickupManager::getInstance().getRepresentation(NULL);
-        this->attach(representation->getSpawnerRepresentation(this));
     }
 
@@ -95,6 +85,14 @@
         this->setMaxSpawnedItems(maxSpawnedItems);
         
-        PickupRepresentation* representation = PickupManager::getInstance().getRepresentation(this->pickup_->getPickupIdentifier());
-        this->attach(representation->getSpawnerRepresentation(this));
+        if(this->pickup_ == NULL)
+        {
+            COUT(2) << "A PickupSpawner was created without a valid Pickupable. This won't work." << std::endl;
+            this->setActive(false);
+        }
+        else
+        {
+            PickupRepresentation* representation = PickupManager::getInstance().getRepresentation(this->pickup_->getPickupIdentifier());
+            this->attach(representation->getSpawnerRepresentation(this));
+        }
     }
 
@@ -109,5 +107,4 @@
         this->triggerDistance_ = 20;
         this->respawnTime_ = 0;
-        this->tickSum_ = 0;
         this->maxSpawnedItems_ = INF;
         this->spawnsRemaining_ = INF;
@@ -141,23 +138,94 @@
         XMLPortParam(PickupSpawner, "respawnTime", setRespawnTime, getRespawnTime, xmlelement, mode);
         XMLPortParam(PickupSpawner, "maxSpawnedItems", setMaxSpawnedItems, getMaxSpawnedItems, xmlelement, mode);
-
-        //TODO: Kill hack.
-        // HACKs
-        // 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();
-//         }
-
-        //  & load the GUI itself too, along with some empty windows
-        //   = even less delays
-//         GUIManager::getInstance().showGUI("PickupInventory");
-//         GUIManager::getInstance().executeCode("hideGUI(\"PickupInventory\")");
-//         PickupInventory::getSingleton();
+        
+        if(this->pickup_ == NULL)
+        {
+            COUT(2) << "A PickupSpawner was created without a valid Pickupable. This won't work." << std::endl;
+            this->setActive(false);
+        }
+        else
+        {
+            PickupRepresentation* representation = PickupManager::getInstance().getRepresentation(this->pickup_->getPickupIdentifier());
+            this->attach(representation->getSpawnerRepresentation(this));
+        }
+    }
+    
+    /**
+    @brief
+        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
+        Tick, checks if any Pawn is close enough to trigger.
+    @param dt
+        Time since last tick.
+    */
+    //TODO: Replace this with a real DistanceTrigger? Or better with collisions?
+    void PickupSpawner::tick(float dt)
+    {
+        //! If the PickupSpawner is active.
+        if (this->isActive())
+        {
+            //! Iterate trough all Pawns.
+            for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
+            {
+                Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
+                //! 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);
+                }
+            }
+        }
+    }
+    
+    /**
+    @brief
+        Sets the maximum number of spawned items.
+    @param items
+        The maximum number of spawned items to be set.
+    */
+    void PickupSpawner::setMaxSpawnedItems(int items)
+    {
+        this->maxSpawnedItems_ = items;
+        this->spawnsRemaining_ = items;
+    }
+    
+    /**
+    @brief
+        Decrements the number of remaining spawns.
+        Sets the PickupSpawner to inactive for the duration of the respawnTime.
+        Destroys the PickupSpawner if the number of remaining spawns has reached zero.
+    */
+    void PickupSpawner::decrementSpawnsRemaining(void)
+    {
+        if(this->spawnsRemaining_ != INF)
+        {
+            this->spawnsRemaining_--;
+        }
+        if(this->spawnsRemaining_ != 0 && this->respawnTime_ > 0)
+        {
+            //TODO: Nicer? Does this even work?
+            this->respawnTimer_.setTimer(this->respawnTime_, false, createExecutor(createFunctor(&PickupSpawner::respawnTimerCallback, this)));
+
+            this->setActive(false);
+            this->fireEvent();
+        }
+        else
+        {
+            COUT(3) << "PickupSpawner empty, selfdestruct initialized." << std::endl;
+            this->setActive(false);
+            this->destroy();
+        }
     }
     
@@ -172,10 +240,10 @@
         if(this->pickup_ != NULL)
         {
-            COUT(1) << "addPickupable called, with this->pickup_ already set." << std::endl;
+            COUT(1) << "In PickupSpawner: setPickupable called, with this->pickup_ already set." << std::endl;
             return;
         }
         if(pickup == NULL)
         {
-            COUT(1) << "Argument of addPickupable is NULL." << std::endl;
+            COUT(1) << "In PickupSpawner: Argument of setPickupable is NULL." << std::endl;
             return;
         }
@@ -197,89 +265,50 @@
     /**
     @brief
-        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
-        Sets the maximum number of spawned items.
-    @param items
-        The maximum number of spawned items to be set.
-    */
-    void PickupSpawner::setMaxSpawnedItems(int items)
-    {
-        this->maxSpawnedItems_ = items;
-        this->spawnsRemaining_ = items;
-    }
-
-    /**
-    @brief
-        Tick, checks if any Pawn is close enough to trigger.
-    @param dt
-        Time since last tick.
-    */
-    //TODO: Replace this with a real DistanceTrigger? Or better with collisions?
-    void PickupSpawner::tick(float dt)
-    {
-        //! If the PickupSpawner is active.
-        if (this->isActive())
-        {
-            //! Iterate trough all Pawns.
-            for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
-            {
-                Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
-                //! 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;
-        }
-    }
-
-    /**
-    @brief
         Trigger the PickupSpawner.
-
-        Adds the pickup to the Pawn that triggered,
-        sets the timer to re-activate and deactives the PickupSpawner.
-
+        Adds the pickup to the Pawn that triggered, sets the timer to re-activate and deactives the PickupSpawner.
     @param pawn
         Pawn which triggered the PickupSpawner.
     */
+    //TODO: Make more generic -> without pawn.
     void PickupSpawner::trigger(Pawn* pawn)
     {
-        //TODO: If private, isActive doesn't need to be tested anymore.
         if (this->isActive()) //!< Checks whether PickupItem is active.
         {
+            PickupCarrier* carrier = dynamic_cast<PickupCarrier*>(pawn);
+            if(carrier == NULL)
+            {
+                COUT(1) << "This is bad. Pawn isn't PickupCarrier." << std::endl;
+                return;
+            }
+            
+            if(!carrier->isTarget(this->pickup_))
+            {
+                COUT(4) << "PickupSpawner triggered but Pawn wasn't a target of the Pickupable." << std::endl;
+                return;
+            }
+            
+            PickupCarrier* target = carrier->getTarget(this->pickup_);
             Pickupable* pickup = this->getPickup();
-            if (pickup != NULL) //!< If everything went ok, and pickup is not NULL.
-            {
-                //TODO: Not correct anymore.
-                PickupCarrier* carrier = dynamic_cast<PickupCarrier*>(pawn);
-                if(carrier == NULL)
-                {
-                    COUT(1) << "This is bad. Pawn isn't PickupCarrier." << std::endl;
-                    return;
-                }
+            
+            if(target != NULL || pickup != NULL)
+            {
+                if(carrier->pickup(pickup))
+                {
+                    this->decrementSpawnsRemaining();
+                }
+                else
+                {
+                    pickup->destroy();
+                }
+            }
+            else
+            {
+                //TODO: Really that severe?
+                if(target == NULL)
+                    COUT(1) << "PickupSpawner: Pickupable has no target." << std::endl;
                 
-                if(carrier->pickup(pickup))
-                {
-                    COUT(3) << "Pickup got picked up." << std::endl;
-
-                    this->decrementSpawnsRemaining();
+                if(pickup == NULL)
+                {
+                    COUT(1) << "PickupSpawner: getPickup produced an error, no Pickupable created." << std::endl;
                 }
                 else
@@ -288,33 +317,4 @@
                 }
             }
-        }
-    }
-    
-    /**
-    @brief
-        Decrements the number of remaining spawns.
-        Sets the PickupSpawner to inactive for the duration of the respawnTime.
-        Destroys the PickupSpawner if the number of remaining spawns has reached zero.
-        
-    */
-    void PickupSpawner::decrementSpawnsRemaining(void)
-    {
-        if(this->spawnsRemaining_ != INF)
-        {
-            this->spawnsRemaining_--;
-        }
-        if(this->spawnsRemaining_ != 0 && this->respawnTime_ > 0)
-        {
-            //TODO: Nicer? Does this even work?
-            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(); //TODO: Implement destroy().
         }
     }
