Index: code/branches/bugger/src/orxonox/objects/quest/GlobalQuest.cc
===================================================================
--- code/branches/bugger/src/orxonox/objects/quest/GlobalQuest.cc	(revision 2529)
+++ code/branches/bugger/src/orxonox/objects/quest/GlobalQuest.cc	(revision 2530)
@@ -26,11 +26,20 @@
  *
  */
+ 
+/**
+    @file GlobalQuest.cc
+    @brief
+    Implementation of the GlobalQuest class.
+*/
 
 #include "OrxonoxStableHeaders.h"
 #include "GlobalQuest.h"
 
+#include "orxonox/objects/infos/PlayerInfo.h"
 #include "core/CoreIncludes.h"
 #include "util/Exception.h"
 
+#include "QuestEffect.h"
+
 namespace orxonox {
 
@@ -39,11 +48,9 @@
     /**
     @brief
-        Constructor.
+        Constructor. Registers the object.
     */
     GlobalQuest::GlobalQuest(BaseObject* creator) : Quest(creator)
     {
         RegisterObject(GlobalQuest);
-
-        this->initialize();
     }
 
@@ -56,20 +63,79 @@
 
     }
-
+    
+    /**
+    @brief
+        Method for creating a GlobalQuest object through XML.
+    */
     void GlobalQuest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
     {
         SUPER(GlobalQuest, XMLPort, xmlelement, mode);
+        
+        XMLPortObject(GlobalQuest, QuestEffect, "reward-effects", addRewardEffect, getRewardEffects, xmlelement, mode);
 
         COUT(3) << "New GlobalQuest {" << this->getId() << "} created." << std::endl;
     }
-
-    void GlobalQuest::initialize(void)
-    {
-        RegisterObject(GlobalQuest);
-    }
-
-    /**
-    @brief
-        Checks whether the quest can be started.
+    
+    /**
+    @brief
+        Fails the Quest for all players.
+        Invokes the fail QuestEffects on all the players possessing this Quest.
+    @param player
+        The player failing it.
+    @return
+        Returns true if the Quest could be failed, false if not.
+    */
+    bool GlobalQuest::fail(PlayerInfo* player)
+    {
+        if(this->isFailable(player)) //!< Check whether the Quest can be failed.
+        {
+            this->setStatus(player, questStatus::failed);
+            
+            //! Iterate through all players possessing this Quest.
+            for(std::set<PlayerInfo*>::const_iterator it = players_.begin(); it != players_.end(); it++)
+            {
+                QuestEffect::invokeEffects(*it, this->getFailEffectList());
+            }
+
+            return true;
+        }
+        
+        COUT(4) << "A non-completable quest was trying to be failed." << std::endl;
+        return false;
+    }
+
+    /**
+    @brief
+        Completes the Quest for all players.
+        Invokes the complete QuestEffects on all the players possessing this Quest.
+        Invokes the reward QuestEffects on the player completing the Quest.
+    @param player
+        The player completing it.
+    @return
+        Returns true if the Quest could be completed, false if not.
+    */
+    bool GlobalQuest::complete(PlayerInfo* player)
+    {
+        if(this->isCompletable(player)) //!< Check whether the Quest can be completed.
+        {
+            this->setStatus(player, questStatus::completed);
+            
+            //! Iterate through all players possessing the Quest.
+            for(std::set<PlayerInfo*>::const_iterator it = players_.begin(); it != players_.end(); it++)
+            {
+                QuestEffect::invokeEffects(*it, this->getCompleteEffectList());
+            }
+            
+            QuestEffect::invokeEffects(player, this->rewards_); //!< Invoke reward QuestEffects on the player completing the Quest.
+            return true;
+        }
+        
+        COUT(4) << "A non-completable quest was trying to be completed." << std::endl;
+        return false;
+    }
+
+    /**
+    @brief
+        Checks whether the Quest can be started.
     @param player
         The player for whom is to be checked.
@@ -79,20 +145,24 @@
         Throws an exception if either isInactive() of isActive() throws one.
     */
-    bool GlobalQuest::isStartable(const Player* player) const
-    {
-        return this->isInactive(player) ||  this->isActive(player);
-    }
-
-    /**
-    @brief
-        Checks whether the quest can be failed.
+    bool GlobalQuest::isStartable(const PlayerInfo* player) const
+    {
+        if(!(this->getParentQuest() == NULL || this->getParentQuest()->isActive(player)))
+        {
+            return false;
+        }
+        return (this->isInactive(player) && !(this->status_ == questStatus::completed || this->status_ == questStatus::failed));
+    }
+
+    /**
+    @brief
+        Checks whether the Quest can be failed.
     @param player
         The player for whom is to be checked.
     @return
-        Returns true if the quest can be failed, false if not.
+        Returns true if the Quest can be failed, false if not.
     @throws
         Throws an Exception if isActive() throws one.
     */
-    bool GlobalQuest::isFailable(const Player* player) const
+    bool GlobalQuest::isFailable(const PlayerInfo* player) const
     {
         return this->isActive(player);
@@ -102,13 +172,13 @@
     /**
     @brief
-        Checks whether the quest can be completed.
+        Checks whether the Quest can be completed.
     @param player
         The player for whom is to be checked.
     @return
-        Returns true if the quest can be completed, false if not.
+        Returns true if the Quest can be completed, false if not.
     @throws
         Throws an Exception if isActive() throws one.
     */
-    bool GlobalQuest::isCompletable(const Player* player) const
+    bool GlobalQuest::isCompletable(const PlayerInfo* player) const
     {
         return this->isActive(player);
@@ -117,5 +187,5 @@
     /**
     @brief
-        Returns the status of the quest for a specific player.
+        Returns the status of the Quest for a specific player.
     @param player
         The player.
@@ -123,22 +193,19 @@
         Throws an Exception if player is NULL.
     */
-    questStatus::Enum GlobalQuest::getStatus(const Player* player) const
-    {
-        if(player == NULL)
-        {
-            ThrowException(Argument, "The input Player* is NULL.");
-        }
-
-        //TDO: Does this really work???
-        std::set<Player*>::const_iterator it = this->players_.find((Player*)(void*)player);
-        if (it != this->players_.end())
+    questStatus::Enum GlobalQuest::getStatus(const PlayerInfo* player) const
+    {
+        if(player == NULL) //!< We don't want NULL-Pointers!
+        {
+            ThrowException(Argument, "The input PlayerInfo* is NULL.");
+        }
+
+        //! Find the player.
+        std::set<PlayerInfo*>::const_iterator it = this->players_.find((PlayerInfo*)(void*)player);
+        if (it != this->players_.end()) //!< If the player was found.
         {
             return this->status_;
         }
-        else
-        {
-           return questStatus::inactive;
-        }
-
+
+    return questStatus::inactive;
     }
 
@@ -154,19 +221,65 @@
         Returns false if player is NULL.
     */
-    bool GlobalQuest::setStatus(Player* player, const questStatus::Enum & status)
-    {
-        if(player == NULL)
+    bool GlobalQuest::setStatus(PlayerInfo* player, const questStatus::Enum & status)
+    {
+        if(player == NULL) //!< We don't want NULL-Pointers!
         {
             return false;
         }
 
-        std::set<Player*>::const_iterator it = this->players_.find(player);
+        //! Find the player.
+        std::set<PlayerInfo*>::const_iterator it = this->players_.find(player);
         if (it == this->players_.end()) //!< Player is not yet in the list.
         {
-            this->players_.insert(player);
-        }
-        this->status_ = status;
+            this->players_.insert(player); //!< Add the player to the set.
+        }
+        
+        this->status_ = status; //!< Set the status, which is global, remember...?
         return true;
     }
+    
+    /**
+    @brief
+        Adds a reward QuestEffect to the list of reward QuestEffects.
+    @param effect
+        The QuestEffect to be added.
+    @return
+        Returns true if successful.
+    */
+    bool GlobalQuest::addRewardEffect(QuestEffect* effect)
+    {
+        if(effect == NULL) //!< We don't want NULL-Pointers!
+        {
+            COUT(2) << "The reward effect to be added to quest {" << this->getId() << "} was NULL." << std::endl;
+            return false;
+        }
+
+        this->rewards_.push_back(effect); //!< Add the QuestEffect to the list.
+
+        COUT(3) << "Reward effect was added to Quest {" << this->getId() << "}." << std::endl;
+        return true;
+    }
+    
+    /**
+    @brief
+        Returns the reward QuestEffect at the given index.
+    @param index
+        The index.
+    @return
+        Returns the QuestEffect at the given index.
+    */
+    const QuestEffect* GlobalQuest::getRewardEffects(unsigned int index) const
+    {
+        int i = index;
+        for (std::list<QuestEffect*>::const_iterator effect = this->rewards_.begin(); effect != this->rewards_.end(); ++effect)
+        {
+            if(i == 0)
+            {
+               return *effect;
+            }
+            i--;
+        }
+        return NULL;
+    }
 
 
