Index: code/branches/pickup2/src/orxonox/CMakeLists.txt
===================================================================
--- code/branches/pickup2/src/orxonox/CMakeLists.txt	(revision 6405)
+++ code/branches/pickup2/src/orxonox/CMakeLists.txt	(revision 6412)
@@ -28,4 +28,5 @@
   LevelManager.cc
   Main.cc
+  MoodManager.cc
   PawnManager.cc
   PlayerManager.cc
@@ -54,4 +55,7 @@
   TOLUA_FILES
     LevelManager.h
+    MoodManager.h
+    controllers/HumanController.h
+    sound/SoundManager.h
   DEFINE_SYMBOL
     "ORXONOX_SHARED_BUILD"
Index: code/branches/pickup2/src/orxonox/CameraManager.cc
===================================================================
--- code/branches/pickup2/src/orxonox/CameraManager.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/CameraManager.cc	(revision 6412)
@@ -45,5 +45,4 @@
 namespace orxonox
 {
-    CameraManager* CameraManager::singletonPtr_s = 0;
     ManageScopedSingleton(CameraManager, ScopeID::Graphics, false);
 
Index: code/branches/pickup2/src/orxonox/Level.cc
===================================================================
--- code/branches/pickup2/src/orxonox/Level.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/Level.cc	(revision 6412)
@@ -141,5 +141,5 @@
     void Level::playerEntered(PlayerInfo* player)
     {
-        COUT(3) << "player entered level (id: " << player->getClientID() << ", name: " << player->getName() << ")" << std::endl;
+        COUT(3) << "player entered level (id: " << player->getClientID() << ", name: " << player->getName() << ')' << std::endl;
         player->setGametype(this->getGametype());
     }
@@ -147,5 +147,5 @@
     void Level::playerLeft(PlayerInfo* player)
     {
-        COUT(3) << "player left level (id: " << player->getClientID() << ", name: " << player->getName() << ")" << std::endl;
+        COUT(3) << "player left level (id: " << player->getClientID() << ", name: " << player->getName() << ')' << std::endl;
         player->setGametype(0);
     }
Index: code/branches/pickup2/src/orxonox/LevelManager.cc
===================================================================
--- code/branches/pickup2/src/orxonox/LevelManager.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/LevelManager.cc	(revision 6412)
@@ -30,10 +30,10 @@
 
 #include <map>
-#include <OgreResourceGroupManager.h>
 
-#include "core/CommandLine.h"
+#include "core/CommandLineParser.h"
 #include "core/ConfigValueIncludes.h"
 #include "core/CoreIncludes.h"
 #include "core/Loader.h"
+#include "core/Resource.h"
 #include "core/ScopedSingletonManager.h"
 #include "PlayerManager.h"
@@ -44,5 +44,4 @@
     SetCommandLineArgument(level, "").shortcut("l").information("Default level file (overrides LevelManager::defaultLevelName_ configValue)");
 
-    LevelManager* LevelManager::singletonPtr_s = 0;
     ManageScopedSingleton(LevelManager, ScopeID::Root, false);
 
@@ -53,7 +52,7 @@
 
         // check override
-        if (!CommandLine::getArgument("level")->hasDefaultValue())
+        if (!CommandLineParser::getArgument("level")->hasDefaultValue())
         {
-            ModifyConfigValue(defaultLevelName_, tset, CommandLine::getValue("level").getString());
+            ModifyConfigValue(defaultLevelName_, tset, CommandLineParser::getValue("level").getString());
         }
     }
@@ -66,5 +65,5 @@
     {
         SetConfigValue(defaultLevelName_, "presentation_dm.oxw")
-            .description("Sets the preselection of the level in the main menu.");
+            .description("Sets the pre selection of the level in the main menu.");
     }
 
@@ -123,8 +122,8 @@
     }
 
-    std::string LevelManager::getAvailableLevelListItem(unsigned int index) const
+    const std::string& LevelManager::getAvailableLevelListItem(unsigned int index) const
     {
         if (index >= availableLevels_.size())
-            return std::string();
+            return BLANKSTRING;
         else
             return availableLevels_[index];
@@ -133,9 +132,5 @@
     void LevelManager::compileAvailableLevelList()
     {
-        availableLevels_.clear();
-
-        availableLevels_ = *Ogre::ResourceGroupManager::getSingleton().findResourceNames(
-            Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "*.oxw");
-
+        availableLevels_ = *Resource::findResourceNames("*.oxw");
         for (std::vector<std::string>::iterator it = availableLevels_.begin(); it != availableLevels_.end();)
             if (it->find("old/") == 0)
Index: code/branches/pickup2/src/orxonox/LevelManager.h
===================================================================
--- code/branches/pickup2/src/orxonox/LevelManager.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/LevelManager.h	(revision 6412)
@@ -60,5 +60,5 @@
             const std::string& getDefaultLevel() const; //tolua_export
             void compileAvailableLevelList(); //tolua_export
-            std::string getAvailableLevelListItem(unsigned int index) const; //tolua_export
+            const std::string& getAvailableLevelListItem(unsigned int index) const; //tolua_export
 
             static LevelManager* getInstancePtr() { return singletonPtr_s; }
Index: code/branches/pickup2/src/orxonox/Main.cc
===================================================================
--- code/branches/pickup2/src/orxonox/Main.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/Main.cc	(revision 6412)
@@ -36,5 +36,5 @@
 #include "OrxonoxPrereqs.h"
 
-#include "core/CommandLine.h"
+#include "core/CommandLineParser.h"
 #include "core/Game.h"
 #include "core/LuaState.h"
@@ -68,7 +68,6 @@
         "  standalone,server,client"
         "   level"
-        " dedicated,dedicatedClient"
+        " server,client"
         "  level"
-        " ioConsole"
         );
 
@@ -76,18 +75,19 @@
 
         // Some development hacks (not really, but in the future, this calls won't make sense anymore)
-        if (CommandLine::getValue("standalone").getBool())
+        if (CommandLineParser::getValue("standalone").getBool())
             Game::getInstance().requestStates("graphics, standalone, level");
-        else if (CommandLine::getValue("server").getBool())
+        else if (CommandLineParser::getValue("server").getBool())
             Game::getInstance().requestStates("graphics, server, level");
-        else if (CommandLine::getValue("client").getBool())
+        else if (CommandLineParser::getValue("client").getBool())
             Game::getInstance().requestStates("graphics, client, level");
-        else if (CommandLine::getValue("dedicated").getBool())
-            Game::getInstance().requestStates("dedicated, level");
-        else if (CommandLine::getValue("dedicatedClient").getBool())
-            Game::getInstance().requestStates("dedicatedClient, level");
-        else if (CommandLine::getValue("console").getBool())
-            Game::getInstance().requestStates("ioConsole");
+        else if (CommandLineParser::getValue("dedicated").getBool())
+            Game::getInstance().requestStates("server, level");
+        else if (CommandLineParser::getValue("dedicatedClient").getBool())
+            Game::getInstance().requestStates("client, level");
         else
-            Game::getInstance().requestStates("graphics, mainMenu");
+        {
+            if (!CommandLineParser::getValue("console").getBool())
+                Game::getInstance().requestStates("graphics, mainMenu");
+        }
 
         game->run();
Index: code/branches/pickup2/src/orxonox/MoodManager.cc
===================================================================
--- code/branches/pickup2/src/orxonox/MoodManager.cc	(revision 6412)
+++ code/branches/pickup2/src/orxonox/MoodManager.cc	(revision 6412)
@@ -0,0 +1,89 @@
+/*
+ *   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:
+ *      Kevin 'youngk' Young
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "MoodManager.h"
+
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "core/ScopedSingletonManager.h"
+
+namespace orxonox
+{
+    ManageScopedSingleton(MoodManager, ScopeID::Root, false);
+
+    MoodManager::MoodManager()
+    {
+        RegisterRootObject(MoodManager);
+        this->setConfigValues();
+    }
+
+    void MoodManager::setConfigValues()
+    {
+        SetConfigValue(mood_, "default")
+            .description("Sets the mood for the current level.")
+            .callback(this, &MoodManager::checkMoodValidity);
+    }
+
+    /** Sets the mood
+    @note
+        TODO: Inform dependent classes of mood change
+    */
+    void MoodManager::setMood(const std::string& mood)
+    {
+        ModifyConfigValue(mood_, set, mood);
+    }
+
+    void MoodManager::checkMoodValidity()
+    {
+        // TODO: Insert new moods here & make this generic
+        if (mood_ != "default" && mood_ != "dnb")
+        {
+            ResetConfigValue(mood_);
+        }
+        else
+        {
+            COUT(3) << "Mood changed to " << mood_ << std::endl;
+            MoodListener::changedMood(mood_);
+        }
+    }
+
+
+    std::string MoodListener::mood_s;
+
+    MoodListener::MoodListener()
+    {
+        RegisterRootObject(MoodListener);
+    }
+
+    /*static*/ void MoodListener::changedMood(const std::string& mood)
+    {
+        mood_s = mood;
+        for (ObjectList<MoodListener>::iterator it = ObjectList<MoodListener>::begin(); it; ++it)
+            it->moodChanged(mood_s);
+    }
+}
Index: code/branches/pickup2/src/orxonox/MoodManager.h
===================================================================
--- code/branches/pickup2/src/orxonox/MoodManager.h	(revision 6412)
+++ code/branches/pickup2/src/orxonox/MoodManager.h	(revision 6412)
@@ -0,0 +1,81 @@
+/*
+ *   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:
+ *      Kevin 'youngk' Young
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MoodManager_H__
+#define _MoodManager_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "util/Singleton.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport MoodListener : virtual public OrxonoxClass
+    {
+        friend class MoodManager;
+
+        protected:
+            MoodListener();
+            virtual ~MoodListener() {}
+
+            const std::string& getMood() const { return mood_s; }
+
+        private:
+            virtual void moodChanged(const std::string& mood) = 0;
+
+            static void changedMood(const std::string& mood);
+            static std::string mood_s;
+    };
+
+    class _OrxonoxExport MoodManager : public Singleton<MoodManager>, public OrxonoxClass
+    {
+            friend class Singleton<MoodManager>;
+        public:
+            MoodManager();
+
+            void setConfigValues();
+
+            void setMood(const std::string& mood);
+            inline const std::string& getMood() const { return this->mood_; }
+
+            static MoodManager& getInstance() { return Singleton<MoodManager>::getInstance(); }
+
+        private:
+            ~MoodManager() {}
+            void checkMoodValidity();
+
+            // config values
+            std::string mood_;
+
+            static MoodManager* singletonPtr_s;
+    };
+}
+
+#endif /* _MoodManager_H__ */
Index: code/branches/pickup2/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- code/branches/pickup2/src/orxonox/OrxonoxPrereqs.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/OrxonoxPrereqs.h	(revision 6412)
@@ -139,5 +139,7 @@
     class AmbientSound;
     class BaseSound;
+    class SoundBuffer;
     class SoundManager;
+    class SoundStreamer;
     class WorldSound;
 
@@ -156,4 +158,5 @@
     class CameraPosition;
     class ControllableEntity;
+    class EffectContainer;
     class ExplosionChunk;
     class MobileEntity;
@@ -163,4 +166,5 @@
     class TeamSpawnPoint;
     class WorldEntity;
+    class Rocket;
     // worldentities, pawns
     class Destroyer;
@@ -196,4 +200,5 @@
 typedef unsigned int ALuint;
 typedef int ALint;
+typedef int ALenum;
 
 #endif /* _OrxonoxPrereqs_H__ */
Index: code/branches/pickup2/src/orxonox/PlayerManager.cc
===================================================================
--- code/branches/pickup2/src/orxonox/PlayerManager.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/PlayerManager.cc	(revision 6412)
@@ -38,5 +38,4 @@
 namespace orxonox
 {
-    PlayerManager* PlayerManager::singletonPtr_s = 0;
     ManageScopedSingleton(PlayerManager, ScopeID::Root, false);
 
@@ -92,4 +91,10 @@
     }
 
+    void PlayerManager::disconnectAllClients()
+    {
+        for( std::map<unsigned int, PlayerInfo*>::iterator it = this->clients_.begin(); it != this->clients_.end(); )
+            this->clientDisconnected( (it++)->first );
+    }
+
 
     PlayerInfo* PlayerManager::getClient(unsigned int clientID) const
Index: code/branches/pickup2/src/orxonox/PlayerManager.h
===================================================================
--- code/branches/pickup2/src/orxonox/PlayerManager.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/PlayerManager.h	(revision 6412)
@@ -52,4 +52,5 @@
             void clientConnected(unsigned int clientID);
             void clientDisconnected(unsigned int clientID);
+            void disconnectAllClients();
 
         private:
Index: code/branches/pickup2/src/orxonox/Radar.cc
===================================================================
--- code/branches/pickup2/src/orxonox/Radar.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/Radar.cc	(revision 6412)
@@ -40,4 +40,6 @@
 #include "core/ObjectList.h"
 #include "interfaces/RadarListener.h"
+#include "controllers/HumanController.h"
+#include "worldentities/pawns/Pawn.h"
 
 namespace orxonox
@@ -45,5 +47,6 @@
 
     Radar::Radar()
-        : focus_(0)
+        : itFocus_(0)
+        , focus_(0)
         , objectTypeCounter_(0)
     {
@@ -82,5 +85,5 @@
     }
 
-    RadarViewable::Shape Radar::addObjectDescription(const std::string name)
+    RadarViewable::Shape Radar::addObjectDescription(const std::string& name)
     {
         std::map<std::string, RadarViewable::Shape>::iterator it = this->objectTypes_.find(name);
@@ -118,5 +121,5 @@
     void Radar::cycleFocus()
     {
-        if (ObjectList<RadarViewable>::begin() == 0)
+        if (ObjectList<RadarViewable>::begin() == ObjectList<RadarViewable>::end())
         {
             // list is empty
@@ -124,13 +127,13 @@
             this->focus_ = 0;
         }
-/*
-        else if (this->owner_)
+
+        else if (HumanController::getLocalControllerEntityAsPawn())
         {
-            Vector3 localPosition = this->owner_->getPosition();
+            Vector3 localPosition = HumanController::getLocalControllerEntityAsPawn()->getWorldPosition();
             Vector3 targetPosition = localPosition;
-            if (*(this->itFocus_))
+            if (this->itFocus_ && *(this->itFocus_))
                 targetPosition = this->itFocus_->getRVWorldPosition();
 
-            // find the closed object further away than targetPosition
+            // find the closest object further away than targetPosition
             float currentDistance = localPosition.squaredDistance(targetPosition);
             float nextDistance = FLT_MAX;
@@ -140,5 +143,5 @@
             for (ObjectList<RadarViewable>::iterator it = ObjectList<RadarViewable>::begin(); it; ++it)
             {
-                if (*it == static_cast<RadarViewable*>(this)->owner_)
+                if (*it == static_cast<RadarViewable*>(HumanController::getLocalControllerEntityAsPawn()))
                     continue;
 
@@ -167,5 +170,4 @@
             }
         }
-*/
     }
 
Index: code/branches/pickup2/src/orxonox/Radar.h
===================================================================
--- code/branches/pickup2/src/orxonox/Radar.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/Radar.h	(revision 6412)
@@ -55,5 +55,5 @@
 
         const RadarViewable* getFocus();
-        RadarViewable::Shape addObjectDescription(const std::string name);
+        RadarViewable::Shape addObjectDescription(const std::string& name);
 
         void listObjects() const;
Index: code/branches/pickup2/src/orxonox/Scene.cc
===================================================================
--- code/branches/pickup2/src/orxonox/Scene.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/Scene.cc	(revision 6412)
@@ -58,4 +58,5 @@
         this->setScene(SmartPtr<Scene>(this, false), OBJECTID_UNKNOWN);
         this->bShadows_ = true;
+        this->soundReferenceDistance_ = 20.0;
 
         if (GameMode::showsGraphics())
@@ -113,4 +114,5 @@
         XMLPortParam(Scene, "ambientlight", setAmbientLight, getAmbientLight, xmlelement, mode).defaultValues(ColourValue(0.2f, 0.2f, 0.2f, 1.0f));
         XMLPortParam(Scene, "shadow", setShadow, getShadow, xmlelement, mode).defaultValues(true);
+        XMLPortParam(Scene, "soundReferenceDistance", setSoundReferenceDistance, getSoundReferenceDistance, xmlelement, mode);
 
         XMLPortParam(Scene, "gravity", setGravity, getGravity, xmlelement, mode);
@@ -334,18 +336,12 @@
     {
         // get the WorldEntity pointers
-        WorldEntity* object0 = static_cast<WorldEntity*>(colObj0->getUserPointer());
-        assert(orxonox_cast<WorldEntity*>(object0));
-        WorldEntity* object1 = static_cast<WorldEntity*>(colObj1->getUserPointer());
-        assert(orxonox_cast<WorldEntity*>(object1));
+        SmartPtr<WorldEntity> object0 = static_cast<WorldEntity*>(colObj0->getUserPointer());
+        SmartPtr<WorldEntity> object1 = static_cast<WorldEntity*>(colObj1->getUserPointer());
 
         // false means that bullet will assume we didn't modify the contact
         bool modified = false;
         if (object0->isCollisionCallbackActive())
-        {
             modified |= object0->collidesAgainst(object1, cp);
-            if (object1->isCollisionCallbackActive())
-                modified |= object1->collidesAgainst(object0, cp);
-        }
-        else
+        if (object1->isCollisionCallbackActive())
             modified |= object1->collidesAgainst(object0, cp);
 
Index: code/branches/pickup2/src/orxonox/Scene.h
===================================================================
--- code/branches/pickup2/src/orxonox/Scene.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/Scene.h	(revision 6412)
@@ -71,7 +71,12 @@
                 { return this->bShadows_; }
 
+            inline void setSoundReferenceDistance(float distance)
+                { this->soundReferenceDistance_ = distance; }
+            inline float getSoundReferenceDistance() const
+                { return this->soundReferenceDistance_; }
+
             inline Radar* getRadar()
                 { return this->radar_; }
-            
+
             inline virtual uint32_t getSceneID() const { return this->getObjectID(); }
 
@@ -96,4 +101,5 @@
             std::list<BaseObject*>   objects_;
             bool                     bShadows_;
+            float                    soundReferenceDistance_;
             Radar*                   radar_;
 
Index: code/branches/pickup2/src/orxonox/Test.cc
===================================================================
--- code/branches/pickup2/src/orxonox/Test.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/Test.cc	(revision 6412)
@@ -36,12 +36,12 @@
 namespace orxonox
 {
-	CreateFactory ( Test );
+    CreateFactory ( Test );
   
-  SetConsoleCommand(Test, printV1, true).accessLevel(AccessLevel::User);
-  SetConsoleCommand(Test, printV2, true).accessLevel(AccessLevel::User);
-  SetConsoleCommand(Test, printV3, true).accessLevel(AccessLevel::User);
-  SetConsoleCommand(Test, printV4, true).accessLevel(AccessLevel::User);
-  SetConsoleCommand(Test, call, true).accessLevel(AccessLevel::User);
-  SetConsoleCommand(Test, call2, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, printV1, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, printV2, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, printV3, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, printV4, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, call, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, call2, true).accessLevel(AccessLevel::User);
   
   
@@ -50,96 +50,101 @@
 //   NetworkFunctionBase* NETWORK_FUNCTION_TEST_C = new NetworkFunctionStatic( createFunctor(&Test::printV1), "bla", NETWORK_FUNCTION_POINTER );
   
-  registerStaticNetworkFunction( &Test::printV1 );
-  registerMemberNetworkFunction( Test, checkU1 );
-  registerMemberNetworkFunction( Test, printBlaBla );
+    registerStaticNetworkFunction( &Test::printV1 );
+    registerMemberNetworkFunction( Test, checkU1 );
+    registerMemberNetworkFunction( Test, printBlaBla );
   
-  Test* Test::instance_ = 0;
+    Test* Test::instance_ = 0;
 
-	Test::Test(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
-	{
-    assert(instance_==0);
-    instance_=this;
-		RegisterObject ( Test );
-    setConfigValues();
-    registerVariables();
-		setSyncMode(0x3);
-	}
+    Test::Test(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
+    {
+        assert(instance_==0);
+        instance_=this;
+        RegisterObject ( Test );
+        setConfigValues();
+        registerVariables();
+        setSyncMode(0x3);
+        this->pointer_ = 0;
+    }
 
-	Test::~Test()
-	{
-    instance_=0;
-	}
+    Test::~Test()
+    {
+        instance_=0;
+    }
 
-	void Test::setConfigValues()
-	{
-		SetConfigValue ( u1, 1 )/*.callback ( this, &Test::checkV1 )*/;
-    SetConfigValue ( u2, 2 )/*.callback ( this, &Test::checkV2 )*/;
-    SetConfigValue ( u3, 3 )/*.callback ( this, &Test::checkV3 )*/;
-    SetConfigValue ( u4, 4 )/*.callback ( this, &Test::checkV4 )*/;
+    void Test::setConfigValues()
+    {
+        SetConfigValue ( u1, 1 )/*.callback ( this, &Test::checkV1 )*/;
+        SetConfigValue ( u2, 2 )/*.callback ( this, &Test::checkV2 )*/;
+        SetConfigValue ( u3, 3 )/*.callback ( this, &Test::checkV3 )*/;
+        SetConfigValue ( u4, 4 )/*.callback ( this, &Test::checkV4 )*/;
     
-    SetConfigValue ( s1, 1 )/*.callback ( this, &Test::checkV1 )*/;
-    SetConfigValue ( s2, 2 )/*.callback ( this, &Test::checkV2 )*/;
-    SetConfigValue ( s3, 3 )/*.callback ( this, &Test::checkV3 )*/;
-    SetConfigValue ( s4, 4 )/*.callback ( this, &Test::checkV4 )*/;
-	}
+        SetConfigValue ( s1, 1 )/*.callback ( this, &Test::checkV1 )*/;
+        SetConfigValue ( s2, 2 )/*.callback ( this, &Test::checkV2 )*/;
+        SetConfigValue ( s3, 3 )/*.callback ( this, &Test::checkV3 )*/;
+        SetConfigValue ( s4, 4 )/*.callback ( this, &Test::checkV4 )*/;
+    }
 
 
-  void Test::registerVariables()
-  {
-    registerVariable ( u1, variableDirection::toclient, new NetworkCallback<Test> ( this, &Test::checkU1 ));
-    registerVariable ( u2, variableDirection::toserver, new NetworkCallback<Test> ( this, &Test::checkU2 ));
-    registerVariable ( u3, variableDirection::serverMaster, new NetworkCallback<Test> ( this, &Test::checkU3 ), true );
-    registerVariable ( u4, variableDirection::clientMaster, new NetworkCallback<Test> ( this, &Test::checkU4 ), true );
+    void Test::registerVariables()
+    {
+        registerVariable ( u1, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::checkU1 ));
+        registerVariable ( u2, VariableDirection::ToServer, new NetworkCallback<Test> ( this, &Test::checkU2 ));
+        registerVariable ( u3, Bidirectionality::ServerMaster, new NetworkCallback<Test> ( this, &Test::checkU3 ), true );
+        registerVariable ( u4, Bidirectionality::ClientMaster, new NetworkCallback<Test> ( this, &Test::checkU4 ), true );
     
-    registerVariable ( s1, variableDirection::toclient, new NetworkCallback<Test> ( this, &Test::checkS1 ));
-    registerVariable ( s2, variableDirection::toserver, new NetworkCallback<Test> ( this, &Test::checkS2 ));
-    registerVariable ( s3, variableDirection::serverMaster, new NetworkCallback<Test> ( this, &Test::checkS3 ), true );
-    registerVariable ( s4, variableDirection::clientMaster, new NetworkCallback<Test> ( this, &Test::checkS4 ), true );
-  }
+        registerVariable ( s1, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::checkS1 ));
+        registerVariable ( s2, VariableDirection::ToServer, new NetworkCallback<Test> ( this, &Test::checkS2 ));
+        registerVariable ( s3, Bidirectionality::ServerMaster, new NetworkCallback<Test> ( this, &Test::checkS3 ), true );
+        registerVariable ( s4, Bidirectionality::ClientMaster, new NetworkCallback<Test> ( this, &Test::checkS4 ), true );
+    
+        registerVariable ( pointer_, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::printPointer ) );
+    }
   
   void Test::call(unsigned int clientID)
-  {
-    callStaticNetworkFunction( &Test::printV1, clientID );
-    callStaticNetworkFunction( &Test::printV1, clientID );
-  }
+    {
+        callStaticNetworkFunction( &Test::printV1, clientID );
+        callStaticNetworkFunction( &Test::printV1, clientID );
+    }
   
-  void Test::call2(unsigned int clientID, std::string s1, std::string s2, std::string s3, std::string s4)
-  {
-    callMemberNetworkFunction( Test, printBlaBla, this->getObjectID(), clientID, s1, s2, s3, s4, s4 );
-  }
+    void Test::call2(unsigned int clientID, std::string s1, std::string s2, std::string s3, std::string s4)
+    {
+        callMemberNetworkFunction( Test, printBlaBla, this->getObjectID(), clientID, s1, s2, s3, s4, s4 );
+    }
   
-  void Test::tick(float dt)
-  {
-//     std::string str1 = "blub";
-//     //MultiType mt1(std::string("blub"));
-//     MultiType mt1(str1);
-//     uint8_t* mem = new uint8_t[mt1.getNetworkSize()];
-//     uint8_t* temp = mem;
-//     mt1.exportData( temp );
-//     assert( temp-mem == mt1.getNetworkSize() );
-//     MultiType mt2;
-//     temp = mem;
-//     mt2.importData( temp );
-//     assert( temp-mem == mt1.getNetworkSize() );
-//     COUT(0) << mt2 << endl;
-    if(!Core::isMaster())
-      call2(0, "bal", "a", "n", "ce");
-//       callMemberNetworkFunction( Test, checkU1, this->getObjectID(), 0 );
-  }
-  
-  void Test::printBlaBla(std::string s1, std::string s2, std::string s3, std::string s4, std::string s5)
-  {
-    COUT(0) << s1 << s2 << s3 << s4 << s5 << endl;
-  }
-  
-  void Test::checkU1(){ COUT(1) << "U1 changed: " << u1 << std::endl; }
-  void Test::checkU2(){ COUT(1) << "U2 changed: " << u2 << std::endl; }
-  void Test::checkU3(){ COUT(1) << "U3 changed: " << u3 << std::endl; }
-  void Test::checkU4(){ COUT(1) << "U4 changed: " << u4 << std::endl; }
+    void Test::tick(float dt)
+    {
+    //     std::string str1 = "blub";
+    //     //MultiType mt1(std::string("blub"));
+    //     MultiType mt1(str1);
+    //     uint8_t* mem = new uint8_t[mt1.getNetworkSize()];
+    //     uint8_t* temp = mem;
+    //     mt1.exportData( temp );
+    //     assert( temp-mem == mt1.getNetworkSize() );
+    //     MultiType mt2;
+    //     temp = mem;
+    //     mt2.importData( temp );
+    //     assert( temp-mem == mt1.getNetworkSize() );
+    //     COUT(0) << mt2 << endl;
+    //     if(!Core::isMaster())
+    //       call2(0, "bal", "a", "n", "ce");
+    //       callMemberNetworkFunction( Test, checkU1, this->getObjectID(), 0 );
+    }
+    
+    void Test::printBlaBla(std::string s1, std::string s2, std::string s3, std::string s4, std::string s5)
+    {
+        COUT(0) << s1 << s2 << s3 << s4 << s5 << endl;
+    }
+    
+    void Test::checkU1(){ COUT(1) << "U1 changed: " << u1 << std::endl; }
+    void Test::checkU2(){ COUT(1) << "U2 changed: " << u2 << std::endl; }
+    void Test::checkU3(){ COUT(1) << "U3 changed: " << u3 << std::endl; }
+    void Test::checkU4(){ COUT(1) << "U4 changed: " << u4 << std::endl; }
 
-  void Test::checkS1(){ COUT(1) << "S1 changed: " << s1 << std::endl; }
-  void Test::checkS2(){ COUT(1) << "S2 changed: " << s2 << std::endl; }
-  void Test::checkS3(){ COUT(1) << "S3 changed: " << s3 << std::endl; }
-  void Test::checkS4(){ COUT(1) << "S4 changed: " << s4 << std::endl; }
+    void Test::checkS1(){ COUT(1) << "S1 changed: " << s1 << std::endl; }
+    void Test::checkS2(){ COUT(1) << "S2 changed: " << s2 << std::endl; }
+    void Test::checkS3(){ COUT(1) << "S3 changed: " << s3 << std::endl; }
+    void Test::checkS4(){ COUT(1) << "S4 changed: " << s4 << std::endl; }
+    
+    void Test::printPointer(){ CCOUT(1) << "pointer: " << this->pointer_ << endl; }
 
 }
Index: code/branches/pickup2/src/orxonox/Test.h
===================================================================
--- code/branches/pickup2/src/orxonox/Test.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/Test.h	(revision 6412)
@@ -76,4 +76,6 @@
       void checkS4();
 
+      void printPointer();
+
       static void printV1(){ instance_->checkU1(); }
       static void printV2(){ instance_->checkU2(); }
@@ -94,4 +96,6 @@
       TYPE s4;
 
+      Test* pointer_;
+
       static Test* instance_;
   };
Index: code/branches/pickup2/src/orxonox/controllers/ArtificialController.cc
===================================================================
--- code/branches/pickup2/src/orxonox/controllers/ArtificialController.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/controllers/ArtificialController.cc	(revision 6412)
@@ -46,5 +46,5 @@
         this->bHasTargetPosition_ = false;
         this->targetPosition_ = Vector3::ZERO;
-        
+
         this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this));
     }
@@ -143,4 +143,8 @@
         this->targetPosition_ = getPredictedPosition(this->getControllableEntity()->getPosition(), hardcoded_projectile_speed, this->target_->getPosition(), this->target_->getVelocity());
         this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO);
+
+        Pawn* pawn = dynamic_cast<Pawn*>(this->getControllableEntity());
+        if (pawn)
+            pawn->setAimPosition(this->targetPosition_);
     }
 
Index: code/branches/pickup2/src/orxonox/controllers/ArtificialController.h
===================================================================
--- code/branches/pickup2/src/orxonox/controllers/ArtificialController.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/controllers/ArtificialController.h	(revision 6412)
@@ -42,5 +42,5 @@
             ArtificialController(BaseObject* creator);
             virtual ~ArtificialController();
-            
+
             void abandonTarget(Pawn* target);
 
Index: code/branches/pickup2/src/orxonox/controllers/CMakeLists.txt
===================================================================
--- code/branches/pickup2/src/orxonox/controllers/CMakeLists.txt	(revision 6405)
+++ code/branches/pickup2/src/orxonox/controllers/CMakeLists.txt	(revision 6412)
@@ -2,4 +2,5 @@
   Controller.cc
   HumanController.cc
+  NewHumanController.cc
   ArtificialController.cc
   AIController.cc
Index: code/branches/pickup2/src/orxonox/controllers/Controller.cc
===================================================================
--- code/branches/pickup2/src/orxonox/controllers/Controller.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/controllers/Controller.cc	(revision 6412)
@@ -29,4 +29,5 @@
 #include "Controller.h"
 #include "core/CoreIncludes.h"
+#include "worldentities/ControllableEntity.h"
 
 namespace orxonox
@@ -40,4 +41,5 @@
         this->player_ = 0;
         this->controllableEntity_ = 0;
+        this->bGodMode_ = false;
     }
 
Index: code/branches/pickup2/src/orxonox/controllers/Controller.h
===================================================================
--- code/branches/pickup2/src/orxonox/controllers/Controller.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/controllers/Controller.h	(revision 6412)
@@ -37,4 +37,8 @@
     class _OrxonoxExport Controller : public BaseObject
     {
+        // set friend classes to access setControllableEntity
+        friend class PlayerInfo;
+        friend class ControllableEntity;
+
         public:
             Controller(BaseObject* creator);
@@ -46,4 +50,15 @@
                 { return this->player_; }
 
+            virtual inline void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage) {};
+
+            void setGodMode( bool mode ){ this->bGodMode_ = mode; }
+            bool getGodMode(){ return this->bGodMode_; }
+
+            inline ControllableEntity* getControllableEntity() const
+                { return this->controllableEntity_; }
+            virtual void changedControllableEntity() {}
+
+        protected:
+            // don't use this directly, use getPlayer()->startControl(entity) (unless you know exactly what you do)
             inline void setControllableEntity(ControllableEntity* entity)
             {
@@ -54,11 +69,10 @@
                 }
             }
-            inline ControllableEntity* getControllableEntity() const
-                { return this->controllableEntity_; }
-            virtual void changedControllableEntity() {}
 
         protected:
             PlayerInfo* player_;
             ControllableEntity* controllableEntity_;
+        private:
+            bool bGodMode_;
     };
 }
Index: code/branches/pickup2/src/orxonox/controllers/HumanController.cc
===================================================================
--- code/branches/pickup2/src/orxonox/controllers/HumanController.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/controllers/HumanController.cc	(revision 6412)
@@ -36,6 +36,4 @@
 #include "infos/PlayerInfo.h"
 #include "overlays/Map.h"
-#include "graphics/Camera.h"
-#include "sound/SoundManager.h"
 #include "Radar.h"
 #include "Scene.h"
@@ -56,4 +54,5 @@
     SetConsoleCommand(HumanController, mouseLook,     true);
     SetConsoleCommand(HumanController, suicide,       true);
+    SetConsoleCommand(HumanController, toggleGodMode, true);
     SetConsoleCommand(HumanController, addBots,       true).defaultValues(1);
     SetConsoleCommand(HumanController, killBots,      true).defaultValues(0);
@@ -71,4 +70,6 @@
         RegisterObject(HumanController);
 
+        controlPaused_ = false;
+
         HumanController::localController_s = this;
     }
@@ -83,12 +84,6 @@
         if (GameMode::playsSound() && HumanController::localController_s && HumanController::localController_s->controllableEntity_)
         {
-            // Update sound listener
             Camera* camera = HumanController::localController_s->controllableEntity_->getCamera();
-            if (camera)
-            {
-                SoundManager::getInstance().setListenerPosition(camera->getWorldPosition());
-                SoundManager::getInstance().setListenerOrientation(camera->getWorldOrientation());
-            }
-            else
+            if (!camera)
                 COUT(3) << "HumanController, Warning: Using a ControllableEntity without Camera" << std::endl;
         }
@@ -97,4 +92,10 @@
     void HumanController::moveFrontBack(const Vector2& value)
     {
+        if (HumanController::localController_s)
+            HumanController::localController_s->frontback(value);
+    }
+
+    void HumanController::frontback(const Vector2& value)
+    {
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
             HumanController::localController_s->controllableEntity_->moveFrontBack(value);
@@ -113,5 +114,5 @@
     }
 
-    void HumanController::rotateYaw(const Vector2& value)
+    void HumanController::yaw(const Vector2& value)
     {
         //Hack to enable mouselook in map
@@ -125,5 +126,5 @@
     }
 
-    void HumanController::rotatePitch(const Vector2& value)
+    void HumanController::pitch(const Vector2& value)
     {
         //Hack to enable mouselook in map
@@ -137,4 +138,16 @@
     }
 
+    void HumanController::rotateYaw(const Vector2& value)
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->yaw(value);
+    }
+
+    void HumanController::rotatePitch(const Vector2& value)
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->pitch(value);
+    }
+
     void HumanController::rotateRoll(const Vector2& value)
     {
@@ -144,4 +157,10 @@
 
     void HumanController::fire(unsigned int firemode)
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->doFire(firemode);
+    }
+
+    void HumanController::doFire(unsigned int firemode)
     {
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
@@ -191,4 +210,9 @@
     }
 
+    void HumanController::toggleGodMode()
+    {
+        HumanController::getLocalControllerSingleton()->setGodMode( !HumanController::getLocalControllerSingleton()->getGodMode() );
+    }
+
     void HumanController::useItem()
     {
@@ -234,3 +258,15 @@
             HumanController::localController_s->controllableEntity_->getScene()->getRadar()->releaseFocus();
     }
+
+    void HumanController::pauseControl()
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->doPauseControl();
+    }
+
+    void HumanController::resumeControl()
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->doResumeControl();
+    }
 }
Index: code/branches/pickup2/src/orxonox/controllers/HumanController.h
===================================================================
--- code/branches/pickup2/src/orxonox/controllers/HumanController.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/controllers/HumanController.h	(revision 6412)
@@ -35,8 +35,11 @@
 #include "Controller.h"
 
+// tolua_begin
 namespace orxonox
 {
-    class _OrxonoxExport HumanController : public Controller, public Tickable
-    {
+    class _OrxonoxExport HumanController
+// tolua_end
+        : public Controller, public Tickable
+    { // tolua_export
         public:
             HumanController(BaseObject* creator);
@@ -53,5 +56,10 @@
             static void rotateRoll(const Vector2& value);
 
+            virtual void frontback(const Vector2& value);
+            virtual void yaw(const Vector2& value);
+            virtual void pitch(const Vector2& value);
+
             static void fire(unsigned int firemode);
+            virtual void doFire(unsigned int firemode);
             static void reload();
 
@@ -66,7 +74,13 @@
 
             static void suicide();
+            static void toggleGodMode();
 
             static void addBots(unsigned int amount);
             static void killBots(unsigned int amount = 0);
+
+            static void pauseControl(); // tolua_export
+            static void resumeControl(); // tolua_export
+            virtual void doPauseControl() {};
+            virtual void doResumeControl() {};
 
             static inline HumanController* getLocalControllerSingleton()
@@ -76,8 +90,9 @@
             friend class Map;
 
-        private:
+        protected:
             static HumanController* localController_s;
-    };
-}
+            bool controlPaused_;
+    }; // tolua_export
+} // tolua_export
 
 #endif /* _HumanController_H__ */
Index: code/branches/pickup2/src/orxonox/controllers/NewHumanController.cc
===================================================================
--- code/branches/pickup2/src/orxonox/controllers/NewHumanController.cc	(revision 6412)
+++ code/branches/pickup2/src/orxonox/controllers/NewHumanController.cc	(revision 6412)
@@ -0,0 +1,576 @@
+/*
+ *   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:
+ *      Michael Wirth
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "NewHumanController.h"
+
+#include <cmath>
+#include <OgreRay.h>
+#include <OgreSceneQuery.h>
+#include <OgreCamera.h>
+#include <OgreSceneManager.h>
+#include <bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h>
+
+#include "core/CoreIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "worldentities/ControllableEntity.h"
+#include "worldentities/pawns/Pawn.h"
+#include "infos/PlayerInfo.h"
+#include "overlays/OrxonoxOverlay.h"
+#include "graphics/Camera.h"
+#include "sound/SoundManager.h"
+#include "tools/BulletConversions.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    SetConsoleCommand(NewHumanController, changeMode, false).keybindMode(KeybindMode::OnPress);
+    SetConsoleCommand(NewHumanController, accelerate, false).keybindMode(KeybindMode::OnPress);
+    SetConsoleCommand(NewHumanController, decelerate, false).keybindMode(KeybindMode::OnPress);
+    SetConsoleCommand(NewHumanController, unfire,      true).keybindMode(KeybindMode::OnRelease);
+
+    CreateUnloadableFactory(NewHumanController);
+
+    NewHumanController* NewHumanController::localController_s = 0;
+
+    NewHumanController::NewHumanController(BaseObject* creator)
+        : HumanController(creator)
+        , crossHairOverlay_(NULL)
+        , centerOverlay_(NULL)
+        , damageOverlayTop_(NULL)
+        , damageOverlayRight_(NULL)
+        , damageOverlayBottom_(NULL)
+        , damageOverlayLeft_(NULL)
+        , damageOverlayTT_(0)
+        , arrowsOverlay1_(NULL)
+        , arrowsOverlay2_(NULL)
+        , arrowsOverlay3_(NULL)
+        , arrowsOverlay4_(NULL)
+    {
+        RegisterObject(NewHumanController);
+
+        overlaySize_ = 0.08;
+        arrowsSize_ = 0.4;
+
+        damageOverlayTime_ = 0.6;
+
+        controlMode_ = 0;
+        acceleration_ = 0;
+        accelerating_ = false;
+        firemode_ = -1;
+
+        showArrows_ = true;
+        showOverlays_ = false;
+        showDamageOverlay_ = true;
+
+        //currentPitch_ = 1;
+        //currentYaw_ = 1;
+
+        if (GameMode::showsGraphics())
+        {
+            crossHairOverlay_ = new OrxonoxOverlay(this);
+            crossHairOverlay_->setBackgroundMaterial("Orxonox/Crosshair3");
+            crossHairOverlay_->setSize(Vector2(overlaySize_, overlaySize_));
+            crossHairOverlay_->hide();
+            //crossHairOverlay_->setAspectCorrection(true); not working
+
+            centerOverlay_ = new OrxonoxOverlay(this);
+            centerOverlay_->setBackgroundMaterial("Orxonox/CenterOverlay");
+            centerOverlay_->setSize(Vector2(overlaySize_ * 2.5, overlaySize_ * 2.5));
+            centerOverlay_->setPosition(Vector2(0.5 - overlaySize_*2.5/2.0, 0.5 - overlaySize_*2.5/2.0));
+            centerOverlay_->hide();
+
+            if (showDamageOverlay_)
+            {
+                damageOverlayTop_ = new OrxonoxOverlay(this);
+                damageOverlayTop_->setBackgroundMaterial("Orxonox/DamageOverlayTop");
+                damageOverlayTop_->setSize(Vector2(overlaySize_ * 2.5, overlaySize_ * 2.5));
+                damageOverlayTop_->setPosition(Vector2(0.5 - overlaySize_*2.5/2.0, 0.5 - overlaySize_*2.5/2.0));
+                damageOverlayTop_->hide();
+
+                damageOverlayRight_ = new OrxonoxOverlay(this);
+                damageOverlayRight_->setBackgroundMaterial("Orxonox/DamageOverlayRight");
+                damageOverlayRight_->setSize(Vector2(overlaySize_ * 2.5, overlaySize_ * 2.5));
+                damageOverlayRight_->setPosition(Vector2(0.5 - overlaySize_*2.5/2.0, 0.5 - overlaySize_*2.5/2.0));
+                damageOverlayRight_->hide();
+
+                damageOverlayBottom_ = new OrxonoxOverlay(this);
+                damageOverlayBottom_->setBackgroundMaterial("Orxonox/DamageOverlayBottom");
+                damageOverlayBottom_->setSize(Vector2(overlaySize_ * 2.5, overlaySize_ * 2.5));
+                damageOverlayBottom_->setPosition(Vector2(0.5 - overlaySize_*2.5/2.0, 0.5 - overlaySize_*2.5/2.0));
+                damageOverlayBottom_->hide();
+
+                damageOverlayLeft_ = new OrxonoxOverlay(this);
+                damageOverlayLeft_->setBackgroundMaterial("Orxonox/DamageOverlayLeft");
+                damageOverlayLeft_->setSize(Vector2(overlaySize_ * 2.5, overlaySize_ * 2.5));
+                damageOverlayLeft_->setPosition(Vector2(0.5 - overlaySize_*2.5/2.0, 0.5 - overlaySize_*2.5/2.0));
+                damageOverlayLeft_->hide();
+            }
+
+            if (showArrows_)
+            {
+                arrowsOverlay1_ = new OrxonoxOverlay(this);
+                arrowsOverlay1_->setBackgroundMaterial("Orxonox/DirectionArrows1");
+                arrowsOverlay1_->setSize(Vector2(0.02727, 0.36 * arrowsSize_));
+                arrowsOverlay1_->setPickPoint(Vector2(0.5, 0.5));
+                arrowsOverlay1_->setPosition(Vector2(0.5, 0.5));
+                arrowsOverlay1_->hide();
+
+                arrowsOverlay2_ = new OrxonoxOverlay(this);
+                arrowsOverlay2_->setBackgroundMaterial("Orxonox/DirectionArrows2");
+                arrowsOverlay2_->setSize(Vector2(0.02727, 0.59 * arrowsSize_));
+                arrowsOverlay2_->setPickPoint(Vector2(0.5, 0.5));
+                arrowsOverlay2_->setPosition(Vector2(0.5, 0.5));
+                arrowsOverlay2_->hide();
+
+                arrowsOverlay3_ = new OrxonoxOverlay(this);
+                arrowsOverlay3_->setBackgroundMaterial("Orxonox/DirectionArrows3");
+                arrowsOverlay3_->setSize(Vector2(0.02727, 0.77 * arrowsSize_));
+                arrowsOverlay3_->setPickPoint(Vector2(0.5, 0.5));
+                arrowsOverlay3_->setPosition(Vector2(0.5, 0.5));
+                arrowsOverlay3_->hide();
+
+                arrowsOverlay4_ = new OrxonoxOverlay(this);
+                arrowsOverlay4_->setBackgroundMaterial("Orxonox/DirectionArrows4");
+                arrowsOverlay4_->setSize(Vector2(0.02727, arrowsSize_));
+                arrowsOverlay4_->setPickPoint(Vector2(0.5, 0.5));
+                arrowsOverlay4_->setPosition(Vector2(0.5, 0.5));
+                arrowsOverlay4_->hide();
+            }
+        }
+
+        // HACK: Define which objects are targetable when considering the creator of an orxonox::Model
+        this->targetMask_.exclude(ClassByString("BaseObject"));
+        this->targetMask_.include(ClassByString("WorldEntity"));
+        this->targetMask_.exclude(ClassByString("Projectile"));
+
+        NewHumanController::localController_s = this;
+
+        controlPaused_ = false;
+
+        //HumanController::localController_s->getControllableEntity()->getCamera()->setDrag(true);
+    }
+
+    NewHumanController::~NewHumanController()
+    {
+        if (this->isInitialized())
+        {
+            if (this->crossHairOverlay_)
+                this->crossHairOverlay_->destroy();
+            if (this->centerOverlay_)
+                this->centerOverlay_->destroy();
+
+            if (showArrows_)
+            {
+                if (this->arrowsOverlay1_)
+                    this->arrowsOverlay1_->destroy();
+                if (this->arrowsOverlay2_)
+                    this->arrowsOverlay2_->destroy();
+                if (this->arrowsOverlay3_)
+                    this->arrowsOverlay3_->destroy();
+                if (this->arrowsOverlay4_)
+                    this->arrowsOverlay4_->destroy();
+            }
+        }
+    }
+
+    void NewHumanController::tick(float dt)
+    {
+        if (GameMode::showsGraphics())
+        {
+
+            if (this->controllableEntity_ && !this->controllableEntity_->isInMouseLook())
+            {
+                this->updateTarget();
+
+                if (!controlPaused_ )
+                {
+                    if (this->getControllableEntity() && (this->getControllableEntity()->isExactlyA(ClassByString("SpaceShip")) || this->getControllableEntity()->isExactlyA(ClassByString("Rocket"))))
+                        this->showOverlays();
+
+                    this->crossHairOverlay_->setPosition(Vector2(static_cast<float>(this->currentYaw_)/2*-1+.5-overlaySize_/2, static_cast<float>(this->currentPitch_)/2*-1+.5-overlaySize_/2));
+
+                    if (this->controlMode_ == 0 || (this->controlMode_ == 1 && this->firemode_ == 1))
+                    {
+                        if (this->showOverlays_ && this->showArrows_)
+                            alignArrows();
+                    }
+                    else
+                        hideArrows();
+
+                    if (this->showDamageOverlay_ && (this->damageOverlayTT_ > 0 || this->damageOverlayTR_ > 0 || this->damageOverlayTB_ > 0 || this->damageOverlayTL_ > 0))
+                    {
+                        this->damageOverlayTT_ -= dt;
+                        this->damageOverlayTR_ -= dt;
+                        this->damageOverlayTB_ -= dt;
+                        this->damageOverlayTL_ -= dt;
+                        if (this->damageOverlayTT_ <= 0)
+                            this->damageOverlayTop_->hide();
+                        if (this->damageOverlayTR_ <= 0)
+                            this->damageOverlayRight_->hide();
+                        if (this->damageOverlayTB_ <= 0)
+                            this->damageOverlayBottom_->hide();
+                        if (this->damageOverlayTL_ <= 0)
+                            this->damageOverlayLeft_->hide();
+                    }
+                }
+            }
+            else
+                this->hideOverlays();
+
+            if (this->acceleration_ > 0)
+            {
+                if (this->accelerating_)
+                    HumanController::moveFrontBack(Vector2(1, 0));
+                else
+                    HumanController::moveFrontBack(Vector2(this->acceleration_, 0));
+                this->accelerating_ = false;
+                //HumanController::moveFrontBack(Vector2(clamp(this->acceleration_ + this->currentAcceleration_, 0.0f, 1.0f), 0));
+            }
+        }
+
+        // Reset pitch and yaw rates
+        // TODO: Reactivate this to fix the game pad problem with 0 input
+        //this->currentPitch_ = 0;
+        //this->currentYaw_ = 0;
+
+        HumanController::tick(dt);
+    }
+
+    void NewHumanController::doFire(unsigned int firemode)
+    {
+        if (!this->controllableEntity_)
+            return;
+
+        this->firemode_ = firemode;
+
+        if (firemode == 1 && this->controlMode_ == 1)
+        {
+            //unlocked steering, steer on right mouse click
+            HumanController::yaw(Vector2(this->currentYaw_, 0));
+            HumanController::pitch(Vector2(this->currentPitch_, 0));
+        }
+        else
+            HumanController::localController_s->getControllableEntity()->fire(firemode);
+
+    }
+
+    void NewHumanController::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
+    {
+        if (this->showDamageOverlay_ && !this->controlPaused_ && this->controllableEntity_ && !this->controllableEntity_->isInMouseLook())
+        {
+            Vector3 posA;
+            if (originator)
+                posA = originator->getWorldPosition();
+            else
+                posA = multi_cast<Vector3>(contactpoint.getPositionWorldOnA());
+            //Vector3 posB = multi_cast<Vector3>(contactpoint.getPositionWorldOnB());
+            //posA and posB are almost identical
+
+            Vector3 relativeHit = this->getControllableEntity()->getWorldOrientation().UnitInverse() * (this->getControllableEntity()->getWorldPosition() - posA);
+
+            //back is z positive
+            //x is left positive
+            //y is down positive
+            relativeHit.normalise();
+
+            float threshold = 0.3;
+            if (relativeHit.x > threshold) // Left
+            {
+                this->damageOverlayLeft_->show();
+                this->damageOverlayTL_ = this->damageOverlayTime_;
+                //this->damageOverlayLeft_->setBackgroundAlpha(0.3);
+            }
+            if (relativeHit.x < -threshold) //Right
+            {
+                this->damageOverlayRight_->show();
+                this->damageOverlayTR_ = this->damageOverlayTime_;
+                //this->damageOverlayRight_->setBackgroundAlpha(0.3);
+            }
+            if (relativeHit.y > threshold) //Top
+            {
+                this->damageOverlayBottom_->show();
+                this->damageOverlayTB_ = this->damageOverlayTime_;
+                //this->damageOverlayTop_->setBackgroundAlpha(0.3);
+            }
+            if (relativeHit.y < -threshold) //Bottom
+            {
+                this->damageOverlayTop_->show();
+                this->damageOverlayTT_ = this->damageOverlayTime_;
+                //this->damageOverlayBottom_->setBackgroundAlpha(0.3);
+            }
+        }
+    }
+
+    void NewHumanController::unfire()
+    {
+        if (NewHumanController::localController_s)
+            NewHumanController::localController_s->doUnfire();
+    }
+
+    void NewHumanController::doUnfire()
+    {
+        this->firemode_ = -1;
+        hideArrows();
+    }
+
+    void NewHumanController::updateTarget()
+    {
+        Ogre::RaySceneQuery * rsq = HumanController::localController_s->getControllableEntity()->getScene()->getSceneManager()->createRayQuery(Ogre::Ray());
+
+        Ogre::Ray mouseRay = HumanController::localController_s->getControllableEntity()->getCamera()->getOgreCamera()->getCameraToViewportRay(static_cast<float>(this->currentYaw_)/2*-1+.5, static_cast<float>(this->currentPitch_)/2*-1+.5);
+
+        rsq->setRay(mouseRay);
+        rsq->setSortByDistance(true);
+
+        /*
+        Distance of objects:
+        ignore everything under 200 maybe even take 1000 as min distance to shoot at
+
+        shots are regularly traced and are entities!!!!!!!!! this is the biggest problem
+        they vanish only after a distance of 10'000
+        */
+
+
+        Ogre::RaySceneQueryResult& result = rsq->execute();
+        Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
+
+        Ogre::RaySceneQueryResult::iterator itr;
+        for (itr = result.begin(); itr != result.end(); ++itr)
+        {
+            if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" && itr->distance > 500)
+            {
+                // Try to cast the user pointer
+                WorldEntity* wePtr = dynamic_cast<WorldEntity*>(itr->movable->getUserObject());
+                if (wePtr)
+                {
+                    // go through all parents of object and look whether they are sightable or not
+                    bool isSightable = false;
+                    WorldEntity* parent = wePtr->getParent();
+                    while (parent)
+                    {
+                        if (this->targetMask_.isExcluded(parent->getIdentifier()))
+                        {
+                            parent = parent->getParent();
+                            continue;
+                        }
+                        else
+                        {
+                            isSightable = true;
+                            break;
+                        }
+                    }
+                    if (!isSightable)
+                        continue;
+                }
+
+                if (this->getControllableEntity() && this->getControllableEntity()->getTarget() != wePtr)
+                    this->getControllableEntity()->setTarget(wePtr);
+
+                if (pawn)
+                    pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance );
+
+                //itr->movable->getParentSceneNode()->showBoundingBox(true);
+                //return mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance; //or itr->movable->getParentSceneNode()->_getDerivedPosition()
+                return;
+            }
+        }
+
+        if (pawn)
+            pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * 1200 );
+
+        if( this->getControllableEntity() && this->getControllableEntity()->getTarget() != 0 )
+            this->getControllableEntity()->setTarget( 0 );
+
+        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getWorldOrientation() * Vector3::NEGATIVE_UNIT_Z * 2000);
+        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getCamera()->getOgreCamera()->getOrientation() * Vector3::NEGATIVE_UNIT_Z);
+    }
+
+    void NewHumanController::frontback(const Vector2& value)
+    {
+        this->accelerating_ = true;
+
+        //if (this->acceleration_ == 0)
+        HumanController::frontback(value);
+    }
+
+    void NewHumanController::yaw(const Vector2& value)
+    {
+        //SUPER(NewHumanController, yaw, value);
+        if (this->controlMode_ == 0 || (this->controllableEntity_ && this->controllableEntity_->isInMouseLook()))
+            HumanController::yaw(value);
+
+        this->currentYaw_ = value.x;
+    }
+
+    void NewHumanController::pitch(const Vector2& value)
+    {
+        //SUPER(NewHumanController, pitch, value);
+        if (this->controlMode_ == 0 || (this->controllableEntity_ && this->controllableEntity_->isInMouseLook()))
+            HumanController::pitch(value);
+
+        this->currentPitch_ = value.x;
+    }
+
+    void NewHumanController::changeMode()
+    {
+        if (NewHumanController::localController_s)
+        {
+            if (NewHumanController::localController_s->controlMode_ == 0)
+            {
+                NewHumanController::localController_s->controlMode_ = 1;
+                NewHumanController::localController_s->hideArrows();
+            }
+            else
+                NewHumanController::localController_s->controlMode_ = 0;
+        }
+    }
+
+    void NewHumanController::changedControllableEntity()
+    {
+        this->controlMode_ = 0;
+        this->currentYaw_ = 0;
+        this->currentPitch_ = 0;
+        if (this->getControllableEntity() && (this->getControllableEntity()->isExactlyA(ClassByString("SpaceShip")) || this->getControllableEntity()->isExactlyA(ClassByString("Rocket"))))
+        {
+            this->showOverlays_ = true;
+            if (!this->controlPaused_)
+            {
+                this->showOverlays();
+                this->alignArrows();
+            }
+        }
+        else
+        {
+            this->showOverlays_ = false;
+            this->hideOverlays();
+        }
+    }
+
+    void NewHumanController::accelerate()
+    {
+        if (NewHumanController::localController_s)
+            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ + 0.2f, 0.00f, 1.0f);
+    }
+
+    void NewHumanController::decelerate()
+    {
+        if (NewHumanController::localController_s)
+            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ - 0.1f, 0.0f, 1.0f);
+    }
+
+    void NewHumanController::doResumeControl()
+    {
+        this->controlPaused_ = false;
+        if (this->showOverlays_)
+            this->showOverlays();
+    }
+
+    void NewHumanController::doPauseControl()
+    {
+        this->controlPaused_ = true;
+        this->hideOverlays();
+    }
+
+    void NewHumanController::alignArrows()
+    {
+        if (showArrows_)
+        {
+            hideArrows();
+
+            float distance = sqrt(pow(static_cast<float>(this->currentYaw_)/2*-1,2) + pow(static_cast<float>(this->currentPitch_)/2*-1,2));
+
+            if (distance > 0.04 && distance <= 0.59 * arrowsSize_ / 2.0 )
+            {
+                this->arrowsOverlay1_->setRotation(Degree(-90 + -1.0 * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
+                this->arrowsOverlay1_->show();
+            }
+            else if (distance > 0.59 * arrowsSize_ / 2.0 && distance <= 0.77 * arrowsSize_ / 2.0 )
+            {
+                this->arrowsOverlay2_->setRotation(Degree(-90 + -1.0 * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
+                this->arrowsOverlay2_->show();
+            }
+            else if (distance > 0.77 * arrowsSize_ / 2.0 && distance <= arrowsSize_ / 2.0)
+            {
+                this->arrowsOverlay3_->setRotation(Degree(-90 + -1.0 * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
+                this->arrowsOverlay3_->show();
+            }
+            else if (distance > arrowsSize_ / 2.0)
+            {
+                this->arrowsOverlay4_->setRotation(Degree(-90 + -1.0 * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
+                this->arrowsOverlay4_->show();
+            }
+        }
+    }
+
+    void NewHumanController::showOverlays()
+    {
+        if (!GameMode::showsGraphics())
+            return;
+        this->crossHairOverlay_->show();
+        this->centerOverlay_->show();
+
+        if (showArrows_)
+        {
+            this->arrowsOverlay1_->show();
+            this->arrowsOverlay2_->show();
+            this->arrowsOverlay3_->show();
+            this->arrowsOverlay4_->show();
+        }
+    }
+
+    void NewHumanController::hideOverlays()
+    {
+        if (!GameMode::showsGraphics())
+            return;
+        this->crossHairOverlay_->hide();
+        this->centerOverlay_->hide();
+
+        if (showDamageOverlay_)
+        {
+            this->damageOverlayTop_->hide();
+            this->damageOverlayRight_->hide();
+            this->damageOverlayBottom_->hide();
+            this->damageOverlayLeft_->hide();
+        }
+
+        this->hideArrows();
+    }
+
+    void NewHumanController::hideArrows()
+    {
+        if(!GameMode::showsGraphics())
+            return;
+        if (showArrows_)
+        {
+            this->arrowsOverlay1_->hide();
+            this->arrowsOverlay2_->hide();
+            this->arrowsOverlay3_->hide();
+            this->arrowsOverlay4_->hide();
+        }
+    }
+}
Index: code/branches/pickup2/src/orxonox/controllers/NewHumanController.h
===================================================================
--- code/branches/pickup2/src/orxonox/controllers/NewHumanController.h	(revision 6412)
+++ code/branches/pickup2/src/orxonox/controllers/NewHumanController.h	(revision 6412)
@@ -0,0 +1,112 @@
+/*
+ *   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:
+ *      Michael Wirth
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NewNewHumanController_H__
+#define _NewNewHumanController_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+
+#include "core/ClassTreeMask.h"
+#include "HumanController.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport NewHumanController : public HumanController
+    {
+        public:
+            NewHumanController(BaseObject* creator);
+            virtual ~NewHumanController();
+
+            virtual void tick(float dt);
+
+            virtual void frontback(const Vector2& value);
+            virtual void yaw(const Vector2& value);
+            virtual void pitch(const Vector2& value);
+
+            static void accelerate();
+            static void decelerate();
+
+            virtual void doFire(unsigned int firemode);
+
+            virtual void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage);
+
+            static void unfire();
+            virtual void doUnfire();
+
+            static void changeMode();
+
+            virtual void changedControllableEntity();
+            virtual void doPauseControl();
+            virtual void doResumeControl();
+
+        protected:
+            void updateTarget();
+            void alignArrows();
+            void showOverlays();
+            void hideOverlays();
+            void hideArrows();
+
+            unsigned int                controlMode_;
+            static NewHumanController*  localController_s;
+
+        private:
+            float                       currentYaw_;
+            float                       currentPitch_;
+            OrxonoxOverlay*             crossHairOverlay_;
+            OrxonoxOverlay*             centerOverlay_;
+
+            OrxonoxOverlay*             damageOverlayTop_;
+            OrxonoxOverlay*             damageOverlayRight_;
+            OrxonoxOverlay*             damageOverlayBottom_;
+            OrxonoxOverlay*             damageOverlayLeft_;
+            float                       damageOverlayTime_;
+            float                       damageOverlayTT_;
+            float                       damageOverlayTR_;
+            float                       damageOverlayTB_;
+            float                       damageOverlayTL_;
+
+            OrxonoxOverlay*             arrowsOverlay1_;
+            OrxonoxOverlay*             arrowsOverlay2_;
+            OrxonoxOverlay*             arrowsOverlay3_;
+            OrxonoxOverlay*             arrowsOverlay4_;
+
+            float                       overlaySize_;
+            float                       arrowsSize_;
+            bool                        accelerating_;
+            float                       acceleration_;
+            int                         firemode_;
+            bool                        showArrows_;
+            bool                        showDamageOverlay_;
+            bool                        showOverlays_;
+            ClassTreeMask               targetMask_;
+    };
+}
+
+#endif /* _NewHumanController_H__ */
Index: code/branches/pickup2/src/orxonox/gamestates/CMakeLists.txt
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/CMakeLists.txt	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/CMakeLists.txt	(revision 6412)
@@ -1,8 +1,5 @@
 ADD_SOURCE_FILES(ORXONOX_SRC_FILES
   GSClient.cc
-  GSDedicated.cc
-  GSDedicatedClient.cc
   GSGraphics.cc
-  GSIOConsole.cc
   GSLevel.cc
   GSMainMenu.cc
Index: code/branches/pickup2/src/orxonox/gamestates/GSClient.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSClient.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/GSClient.cc	(revision 6412)
@@ -29,7 +29,7 @@
 #include "GSClient.h"
 
-#include "util/Clock.h"
+#include "util/Debug.h"
 #include "util/Exception.h"
-#include "core/CommandLine.h"
+#include "core/CommandLineParser.h"
 #include "core/Game.h"
 #include "core/GameMode.h"
@@ -38,5 +38,5 @@
 namespace orxonox
 {
-    DeclareGameState(GSClient, "client", false, true);
+    DeclareGameState(GSClient, "client", false, false);
 
     SetCommandLineArgument(ip, "127.0.0.1").information("Sever IP as string in the form #.#.#.#");
@@ -56,5 +56,5 @@
         GameMode::setIsClient(true);
 
-        this->client_ = new Client(CommandLine::getValue("ip").getString(), CommandLine::getValue("port"));
+        this->client_ = new Client(CommandLineParser::getValue("ip").getString(), CommandLineParser::getValue("port"));
 
         if(!client_->establishConnection())
Index: code/branches/pickup2/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSDedicated.cc	(revision 6405)
+++ 	(revision )
@@ -1,301 +1,0 @@
-/*
- *   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:
- *      Reto Grieder
- *   Co-authors:
- *      Fabian 'x3n' Landau
- *
- */
-
-#include "GSDedicated.h"
-
-#include <iomanip>
-#include <iostream>
-#include <boost/bind.hpp>
-
-#include "util/Clock.h"
-#include "util/Debug.h"
-#include "util/Sleep.h"
-#include "core/CommandLine.h"
-#include "core/CommandExecutor.h"
-#include "core/Game.h"
-#include "core/GameMode.h"
-#include "network/Server.h"
-
-#ifdef ORXONOX_PLATFORM_UNIX
-#include <termios.h>
-#endif
-
-
-namespace orxonox
-{
-    const unsigned int MAX_COMMAND_LENGTH = 255;
-    
-    DeclareGameState(GSDedicated, "dedicated", false, false);
-    
-    termios* GSDedicated::originalTerminalSettings_;
-
-    GSDedicated::GSDedicated(const GameStateInfo& info)
-        : GameState(info)
-        , server_(0)
-        , closeThread_(false)
-        , cleanLine_(true)
-        , inputIterator_(0)
-        , cursorX_(0)
-        , cursorY_(0)
-    {
-    }
-
-    GSDedicated::~GSDedicated()
-    {
-    }
-
-    void GSDedicated::activate()
-    {
-        GameMode::setHasServer(true);
-        
-        this->inputThread_ = new boost::thread(boost::bind(&GSDedicated::inputThread, this));
-        
-#ifndef ORXONOX_PLATFORM_WINDOWS
-        this->originalTerminalSettings_ = new termios;
-        this->setTerminalMode();
-#endif
-
-        this->server_ = new Server(CommandLine::getValue("port"));
-        COUT(0) << "Loading scene in server mode" << std::endl;
-
-        server_->open();
-    }
-
-    void GSDedicated::deactivate()
-    {
-        this->server_->close();
-        delete this->server_;
-        
-        closeThread_ = true;
-#ifdef ORXONOX_PLATFORM_UNIX
-        std::cout << "\033[0G\033[K";
-        std::cout.flush();
-        resetTerminalMode();
-        delete this->originalTerminalSettings_;
-#else
-        COUT(0) << "Press enter to end the game..." << std::endl;
-#endif
-        inputThread_->join();
-        delete this->inputThread_;
-
-        GameMode::setHasServer(false);
-    }
-
-    void GSDedicated::update(const Clock& time)
-    {
-        server_->update(time);
-        processQueue();
-        printLine();
-    }
-    
-    void GSDedicated::inputThread()
-    {
-        this->commandLine_ = new unsigned char[MAX_COMMAND_LENGTH];
-//         memset( this->commandLine_, 0, MAX_COMMAND_LENGTH );
-        unsigned char c;
-        unsigned int  escapeChar=0;
-        while(!closeThread_)
-        {
-#ifdef ORXONOX_PLATFORM_UNIX
-            size_t count = read(STDIN_FILENO, &c, 1);
-            if (count == 1)
-#else
-            c = getchar();
-#endif
-            {
-//                 boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-                if ( inputIterator_>=MAX_COMMAND_LENGTH-1 && c!='\n' )
-                    continue;
-                if( escapeChar > 0 )
-                {
-                    if( c == '[' )
-                    {
-                        escapeChar = 2;
-                        continue;
-                    }
-                    else if ( escapeChar == 2 )
-                    {
-                        switch (c)
-                        {
-                            case 'A': //keyup
-                                
-                                break;
-                            case 'B': //keydown
-                                
-                                break;
-                            case 'C': //keyright
-                                if(cursorX_<inputIterator_)
-                                    ++cursorX_;
-                                break;
-                            case 'D': //keyleft
-                                if(cursorX_>0)
-                                    --cursorX_;
-                                break;
-                            default: //not supported...
-//                                 std::cout << endl << c << endl;
-                                break;
-                        }
-                        escapeChar = 0;
-                    }
-                }
-                else // not in escape sequence mode
-                {
-                    switch (c)
-                    {
-                        case '\n':
-                            this->cleanLine_ = true;
-                            {
-                                boost::recursive_mutex::scoped_lock(this->inputQueueMutex_);
-                                boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-                                this->commandQueue_.push( std::string((const char*)this->commandLine_,inputIterator_) );
-                            }
-                            memset( this->commandLine_, 0, inputIterator_ );
-                            inputIterator_ = 0;
-                            this->cursorX_ = 0;
-                            this->cursorY_ = 0;
-                            std::cout << endl;
-                            break;
-                        case 127: // backspace
-                        case '\b':
-                            deleteCharacter( this->cursorX_ );
-                            break;
-                        case '\t':
-                        {
-//                             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-                            std::cout << endl << CommandExecutor::hint( std::string((const char*)this->commandLine_,inputIterator_) ) << endl;
-                            strncpy(reinterpret_cast<char*>(this->commandLine_), CommandExecutor::complete( std::string(reinterpret_cast<char*>(this->commandLine_),inputIterator_) ).c_str(), MAX_COMMAND_LENGTH);
-                            this->inputIterator_ = strlen((const char*)this->commandLine_);
-                            this->cursorX_ = this->inputIterator_;
-                            break;
-                        }
-                        case '\033': // 1. escape character
-                            escapeChar = 1;
-                            break;
-                        default:
-                            insertCharacter( this->cursorX_, c );
-                            break;
-                    }
-                }
-            }
-        }
-
-        delete[] this->commandLine_;
-    }
-    
-    void GSDedicated::printLine()
-    {
-#ifdef ORXONOX_PLATFORM_UNIX
-        // set cursor to the begining of the line and erase the line
-        std::cout << "\033[0G\033[K";
-//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-        // print status line
-        std::cout << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, " << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms avg ticktime # ";
-        //save cursor position
-        std::cout << "\033[s";
-        //print commandLine buffer
-        std::cout << std::string((const char*)this->commandLine_, inputIterator_);
-        //restore cursor position and move it cursorX_ to the right
-        std::cout << "\033[u";
-        if( this->cursorX_ > 0 )
-            std::cout << "\033[" << this->cursorX_ << "C";
-        std::cout.flush();
-#endif
-    }
-    
-    void GSDedicated::processQueue()
-    {
-        std::string tempstr;
-        {
-            boost::recursive_mutex::scoped_lock lock1(this->inputQueueMutex_);
-            while(true)
-            {
-                if ( !this->commandQueue_.empty() )
-                {
-                    tempstr = this->commandQueue_.front();
-                    this->commandQueue_.pop();
-                    lock1.unlock();
-                }
-                else
-                    break;
-                CommandExecutor::execute(tempstr, true);
-            }
-        }
-    }
-    
-    void GSDedicated::setTerminalMode()
-    {
-#ifdef ORXONOX_PLATFORM_UNIX
-        termios new_settings;
-     
-        tcgetattr(0,this->originalTerminalSettings_);
-        new_settings = *this->originalTerminalSettings_;
-        new_settings.c_lflag &= ~( ICANON | ECHO );
-//         new_settings.c_lflag |= ( ISIG | IEXTEN );
-        new_settings.c_cc[VTIME] = 1;
-        new_settings.c_cc[VMIN] = 0;
-        tcsetattr(0,TCSANOW,&new_settings);
-        COUT(0) << endl;
-//       atexit(&GSDedicated::resetTerminalMode);
-#endif
-    }
-    
-    void GSDedicated::resetTerminalMode()
-    {
-#ifdef ORXONOX_PLATFORM_UNIX
-        tcsetattr(0, TCSANOW, GSDedicated::originalTerminalSettings_);
-#endif
-    }
-    
-    void GSDedicated::insertCharacter( unsigned int position, char c )
-    {
-//         std::cout << endl << static_cast<unsigned int>(c) << endl;
-        // check that we do not exceed MAX_COMMAND_LENGTH
-        if( inputIterator_+1 < MAX_COMMAND_LENGTH )
-        {
-            // if cursor not at end of line then move the rest of the line
-            if( position != this->inputIterator_ )
-                    memmove( this->commandLine_+position+1, this->commandLine_+position, this->inputIterator_-position);
-//             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-            this->commandLine_[position] = c;
-            ++this->cursorX_;
-            ++this->inputIterator_;
-        }
-    }
-    void GSDedicated::deleteCharacter( unsigned int position )
-    {
-//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-        if ( this->inputIterator_>0 && position>0 )
-        {
-            if ( position != this->inputIterator_ )
-                memmove( this->commandLine_+position-1, this->commandLine_+position, this->inputIterator_-position);
-            --this->cursorX_;
-            --this->inputIterator_;
-        }
-    }
-    
-}
Index: code/branches/pickup2/src/orxonox/gamestates/GSDedicated.h
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSDedicated.h	(revision 6405)
+++ 	(revision )
@@ -1,85 +1,0 @@
-/*
- *   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:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-#ifndef _GSDedicated_H__
-#define _GSDedicated_H__
-
-#include "OrxonoxPrereqs.h"
-
-#include <cstring>
-#include <queue>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/recursive_mutex.hpp>
-
-#include "core/GameState.h"
-#include "network/NetworkPrereqs.h"
-
-struct termios;
-
-namespace orxonox
-{
-
-    class _OrxonoxExport GSDedicated : public GameState
-    {
-    public:
-        GSDedicated(const GameStateInfo& info);
-        ~GSDedicated();
-
-        void activate();
-        void deactivate();
-        void update(const Clock& time);
-
-    private:
-        void inputThread();
-        void printLine();
-        void processQueue();
-        void setTerminalMode();
-        static void resetTerminalMode();
-
-        void insertCharacter( unsigned int position, char c );
-        void deleteCharacter( unsigned int position );
-
-        Server*                 server_;
-
-        boost::thread           *inputThread_;
-        boost::recursive_mutex  inputLineMutex_;
-        boost::recursive_mutex  inputQueueMutex_;
-        bool                    closeThread_;
-        bool                    cleanLine_;
-        unsigned char*          commandLine_;
-        unsigned int            inputIterator_;
-        std::queue<std::string> commandQueue_;
-        static termios*         originalTerminalSettings_;
-
-        unsigned int            cursorX_;
-        unsigned int            cursorY_;
-    };
-}
-
-#endif /* _GSDedicated_H__ */
Index: code/branches/pickup2/src/orxonox/gamestates/GSDedicatedClient.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSDedicatedClient.cc	(revision 6405)
+++ 	(revision )
@@ -1,306 +1,0 @@
-/*
- *   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:
- *      Reto Grieder
- *   Co-authors:
- *      Oliver Scheuss
- *
- */
-
-#include "GSDedicatedClient.h"
-
-#include <iomanip>
-#include <iostream>
-#include <boost/bind.hpp>
-
-#include "util/Clock.h"
-#include "util/Debug.h"
-#include "util/Exception.h"
-#include "util/Sleep.h"
-#include "core/CommandLine.h"
-#include "core/CommandExecutor.h"
-#include "core/Game.h"
-#include "core/GameMode.h"
-#include "network/Client.h"
-
-#ifdef ORXONOX_PLATFORM_UNIX
-#include <termios.h>
-#endif
-
-
-namespace orxonox
-{
-    const unsigned int MAX_COMMAND_LENGTH = 255;
-    
-    DeclareGameState(GSDedicatedClient, "dedicatedClient", false, false);
-    
-    termios* GSDedicatedClient::originalTerminalSettings_;
-
-    GSDedicatedClient::GSDedicatedClient(const GameStateInfo& info)
-        : GameState(info)
-        , client_(0)
-        , closeThread_(false)
-        , cleanLine_(true)
-        , inputIterator_(0)
-        , cursorX_(0)
-        , cursorY_(0)
-    {
-    }
-
-    GSDedicatedClient::~GSDedicatedClient()
-    {
-    }
-
-    void GSDedicatedClient::activate()
-    {
-        this->inputThread_ = new boost::thread(boost::bind(&GSDedicatedClient::inputThread, this));
-        
-#ifndef ORXONOX_PLATFORM_WINDOWS
-        this->originalTerminalSettings_ = new termios;
-        this->setTerminalMode();
-#endif
-
-        this->client_ = new Client(CommandLine::getValue("ip").getString(), CommandLine::getValue("port"));
-        COUT(0) << "Loading scene in client mode" << std::endl;
-
-        if( !client_->establishConnection() )
-            ThrowException(InitialisationFailed, "Could not establish connection with server.");
-            
-        client_->update(Game::getInstance().getGameClock());
-
-
-    }
-
-    void GSDedicatedClient::deactivate()
-    {
-        if( this->client_ )
-        {
-            this->client_->closeConnection();
-            delete this->client_;
-        }
-        
-        closeThread_ = true;
-#ifdef ORXONOX_PLATFORM_UNIX
-        std::cout << "\033[0G\033[K";
-        std::cout.flush();
-        resetTerminalMode();
-        delete this->originalTerminalSettings_;
-#else
-        COUT(0) << "Press enter to end the game..." << std::endl;
-#endif
-        inputThread_->join();
-        delete this->inputThread_;
-    }
-
-    void GSDedicatedClient::update(const Clock& time)
-    {
-        client_->update(time);
-        processQueue();
-        printLine();
-    }
-    
-    void GSDedicatedClient::inputThread()
-    {
-        this->commandLine_ = new unsigned char[MAX_COMMAND_LENGTH];
-//         memset( this->commandLine_, 0, MAX_COMMAND_LENGTH );
-        unsigned char c;
-        unsigned int  escapeChar=0;
-        while(!closeThread_)
-        {
-#ifdef ORXONOX_PLATFORM_UNIX
-            size_t count = read(STDIN_FILENO, &c, 1);
-            if (count == 1)
-#else
-            c = getchar();
-#endif
-            {
-//                 boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-                if ( inputIterator_>=MAX_COMMAND_LENGTH-1 && c!='\n' )
-                    continue;
-                if( escapeChar > 0 )
-                {
-                    if( c == '[' )
-                    {
-                        escapeChar = 2;
-                        continue;
-                    }
-                    else if ( escapeChar == 2 )
-                    {
-                        switch (c)
-                        {
-                            case 'A': //keyup
-                                
-                                break;
-                            case 'B': //keydown
-                                
-                                break;
-                            case 'C': //keyright
-                                if(cursorX_<inputIterator_)
-                                    ++cursorX_;
-                                break;
-                            case 'D': //keyleft
-                                if(cursorX_>0)
-                                    --cursorX_;
-                                break;
-                            default: //not supported...
-//                                 std::cout << endl << c << endl;
-                                break;
-                        }
-                        escapeChar = 0;
-                    }
-                }
-                else // not in escape sequence mode
-                {
-                    switch (c)
-                    {
-                        case '\n':
-                            this->cleanLine_ = true;
-                            {
-                                boost::recursive_mutex::scoped_lock(this->inputQueueMutex_);
-                                boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-                                this->commandQueue_.push( std::string((const char*)this->commandLine_,inputIterator_) );
-                            }
-                            memset( this->commandLine_, 0, inputIterator_ );
-                            inputIterator_ = 0;
-                            this->cursorX_ = 0;
-                            this->cursorY_ = 0;
-                            std::cout << endl;
-                            break;
-                        case 127: // backspace
-                        case '\b':
-                            deleteCharacter( this->cursorX_ );
-                            break;
-                        case '\t':
-                        {
-//                             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-                            std::cout << endl << CommandExecutor::hint( std::string((const char*)this->commandLine_,inputIterator_) ) << endl;
-                            strncpy(reinterpret_cast<char*>(this->commandLine_), CommandExecutor::complete( std::string(reinterpret_cast<char*>(this->commandLine_),inputIterator_) ).c_str(), MAX_COMMAND_LENGTH);
-                            this->inputIterator_ = strlen((const char*)this->commandLine_);
-                            this->cursorX_ = this->inputIterator_;
-                            break;
-                        }
-                        case '\033': // 1. escape character
-                            escapeChar = 1;
-                            break;
-                        default:
-                            insertCharacter( this->cursorX_, c );
-                            break;
-                    }
-                }
-            }
-        }
-
-        delete[] this->commandLine_;
-    }
-    
-    void GSDedicatedClient::printLine()
-    {
-#ifdef ORXONOX_PLATFORM_UNIX
-        // set cursor to the begining of the line and erase the line
-        std::cout << "\033[0G\033[K";
-//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-        // print status line
-        std::cout << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, " << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms avg ticktime # ";
-        //save cursor position
-        std::cout << "\033[s";
-        //print commandLine buffer
-        std::cout << std::string((const char*)this->commandLine_, inputIterator_);
-        //restore cursor position and move it cursorX_ to the right
-        std::cout << "\033[u";
-        if( this->cursorX_ > 0 )
-            std::cout << "\033[" << this->cursorX_ << "C";
-        std::cout.flush();
-#endif
-    }
-    
-    void GSDedicatedClient::processQueue()
-    {
-        std::string tempstr;
-        {
-            boost::recursive_mutex::scoped_lock lock1(this->inputQueueMutex_);
-            while(true)
-            {
-                if ( !this->commandQueue_.empty() )
-                {
-                    tempstr = this->commandQueue_.front();
-                    this->commandQueue_.pop();
-                    lock1.unlock();
-                }
-                else
-                    break;
-                CommandExecutor::execute(tempstr, true);
-            }
-        }
-    }
-    
-    void GSDedicatedClient::setTerminalMode()
-    {
-#ifdef ORXONOX_PLATFORM_UNIX
-        termios new_settings;
-     
-        tcgetattr(0,this->originalTerminalSettings_);
-        new_settings = *this->originalTerminalSettings_;
-        new_settings.c_lflag &= ~( ICANON | ECHO );
-//         new_settings.c_lflag |= ( ISIG | IEXTEN );
-        new_settings.c_cc[VTIME] = 1;
-        new_settings.c_cc[VMIN] = 0;
-        tcsetattr(0,TCSANOW,&new_settings);
-        COUT(0) << endl;
-//       atexit(&GSDedicatedClient::resetTerminalMode);
-#endif
-    }
-    
-    void GSDedicatedClient::resetTerminalMode()
-    {
-#ifdef ORXONOX_PLATFORM_UNIX
-        tcsetattr(0, TCSANOW, GSDedicatedClient::originalTerminalSettings_);
-#endif
-    }
-    
-    void GSDedicatedClient::insertCharacter( unsigned int position, char c )
-    {
-//         std::cout << endl << static_cast<unsigned int>(c) << endl;
-        // check that we do not exceed MAX_COMMAND_LENGTH
-        if( inputIterator_+1 < MAX_COMMAND_LENGTH )
-        {
-            // if cursor not at end of line then move the rest of the line
-            if( position != this->inputIterator_ )
-                    memmove( this->commandLine_+position+1, this->commandLine_+position, this->inputIterator_-position);
-//             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-            this->commandLine_[position] = c;
-            ++this->cursorX_;
-            ++this->inputIterator_;
-        }
-    }
-    void GSDedicatedClient::deleteCharacter( unsigned int position )
-    {
-//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
-        if ( this->inputIterator_>0 && position>0 )
-        {
-            if ( position != this->inputIterator_ )
-                memmove( this->commandLine_+position-1, this->commandLine_+position, this->inputIterator_-position);
-            --this->cursorX_;
-            --this->inputIterator_;
-        }
-    }
-    
-}
Index: code/branches/pickup2/src/orxonox/gamestates/GSDedicatedClient.h
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSDedicatedClient.h	(revision 6405)
+++ 	(revision )
@@ -1,84 +1,0 @@
-/*
- *   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:
- *      Reto Grieder
- *   Co-authors:
- *      Oliver Scheuss
- *
- */
-
-#ifndef _GSDedicatedClient_H__
-#define _GSDedicatedClient_H__
-
-#include "OrxonoxPrereqs.h"
-
-#include "core/GameState.h"
-#include "network/NetworkPrereqs.h"
-#include <queue>
-#include <cstring>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/recursive_mutex.hpp>
-
-struct termios;
-
-namespace orxonox
-{
-
-    class _OrxonoxExport GSDedicatedClient : public GameState
-    {
-    public:
-        GSDedicatedClient(const GameStateInfo& info);
-        ~GSDedicatedClient();
-
-        void activate();
-        void deactivate();
-        void update(const Clock& time);
-
-    private:
-        void inputThread();
-        void printLine();
-        void processQueue();
-        void setTerminalMode();
-        static void resetTerminalMode();
-
-        void insertCharacter( unsigned int position, char c );
-        void deleteCharacter( unsigned int position );
-
-        Client*                 client_;
-
-        boost::thread           *inputThread_;
-        boost::recursive_mutex  inputLineMutex_;
-        boost::recursive_mutex  inputQueueMutex_;
-        bool                    closeThread_;
-        bool                    cleanLine_;
-        unsigned char*          commandLine_;
-        unsigned int            inputIterator_;
-        std::queue<std::string> commandQueue_;
-        static termios*         originalTerminalSettings_;
-
-        unsigned int            cursorX_;
-        unsigned int            cursorY_;
-    };
-}
-
-#endif /* _GSDedicatedClient_H__ */
Index: code/branches/pickup2/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSGraphics.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/GSGraphics.cc	(revision 6412)
@@ -64,6 +64,5 @@
     void GSGraphics::activate()
     {
-        // add console command to toggle GUI
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSGraphics::toggleGUI, this), "toggleGUI"));
+
     }
 
@@ -78,16 +77,4 @@
     }
 
-    /**
-    @brief
-        Toggles the visibility of the current GUI
-
-        This function just executes a Lua function in the main script of the GUI by accessing the GUIManager.
-        For more details on this function check out the Lua code.
-    */
-    void GSGraphics::toggleGUI()
-    {
-        GUIManager::getInstance().executeCode("toggleGUI()");
-    }
-
     void GSGraphics::update(const Clock& time)
     {
Index: code/branches/pickup2/src/orxonox/gamestates/GSGraphics.h
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSGraphics.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/GSGraphics.h	(revision 6412)
@@ -57,6 +57,4 @@
         void update(const Clock& time);
 
-        void toggleGUI();
-
     private:
     };
Index: code/branches/pickup2/src/orxonox/gamestates/GSIOConsole.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSIOConsole.cc	(revision 6405)
+++ 	(revision )
@@ -1,71 +1,0 @@
-/*
- *   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:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-#include "GSIOConsole.h"
-
-#include <iostream>
-#include "core/ConsoleCommand.h"
-#include "core/CommandExecutor.h"
-#include "core/Game.h"
-
-namespace orxonox
-{
-    DeclareGameState(GSIOConsole, "ioConsole", false, false);
-
-    GSIOConsole::GSIOConsole(const GameStateInfo& info)
-        : GameState(info)
-    {
-    }
-
-    GSIOConsole::~GSIOConsole()
-    {
-    }
-
-    void GSIOConsole::activate()
-    {
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSIOConsole::loadMenu, this), "loadMenu"));
-    }
-
-    void GSIOConsole::deactivate()
-    {
-    }
-
-    void GSIOConsole::update(const Clock& time)
-    {
-        std::cout << ">";
-        std::string command;
-        std::getline(std::cin, command);
-        CommandExecutor::execute(command, true);
-    }
-
-    void GSIOConsole::loadMenu()
-    {
-        Game::getInstance().popState();
-        Game::getInstance().requestStates("graphics, mainMenu");
-    }
-}
Index: code/branches/pickup2/src/orxonox/gamestates/GSIOConsole.h
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSIOConsole.h	(revision 6405)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- *   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:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-#ifndef _GSIOConsole_H__
-#define _GSIOConsole_H__
-
-#include "OrxonoxPrereqs.h"
-#include "core/GameState.h"
-
-namespace orxonox
-{
-    class _OrxonoxExport GSIOConsole : public GameState
-    {
-    public:
-        GSIOConsole(const GameStateInfo& info);
-        ~GSIOConsole();
-
-        void activate();
-        void deactivate();
-        void update(const Clock& time);
-
-    private:
-        void loadMenu();
-    };
-}
-
-#endif /* _GSIOConsole_H__ */
Index: code/branches/pickup2/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSLevel.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/GSLevel.cc	(revision 6412)
@@ -56,4 +56,5 @@
         , guiKeysOnlyInputState_(0)
         , startFile_(0)
+        , bShowIngameGUI_(false)
     {
     }
@@ -78,6 +79,4 @@
             guiKeysOnlyInputState_ = InputManager::getInstance().createInputState("guiKeysOnly");
             guiKeysOnlyInputState_->setKeyHandler(GUIManager::getInstancePtr());
-
-            CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSLevel::showIngameGUI, this), "showIngameGUI"));
         }
 
@@ -91,23 +90,7 @@
             // level is loaded: we can start capturing the input
             InputManager::getInstance().enterState("game");
-            
+
             // connect the HumanPlayer to the game
             PlayerManager::getInstance().clientConnected(0);
-        }
-    }
-
-    void GSLevel::showIngameGUI(bool show)
-    {
-        if (show)
-        {
-            GUIManager::getInstance().showGUI("inGameTest");
-            GUIManager::getInstance().executeCode("showCursor()");
-            InputManager::getInstance().enterState("guiMouseOnly");
-        }
-        else
-        {
-            GUIManager::getInstance().executeCode("hideGUI(\"inGameTest\")");
-            GUIManager::getInstance().executeCode("hideCursor()");
-            InputManager::getInstance().leaveState("guiMouseOnly");
         }
     }
@@ -117,7 +100,4 @@
         if (GameMode::showsGraphics())
         {
-            // disconnect the HumanPlayer
-            PlayerManager::getInstance().clientDisconnected(0);
-            
             // unload all compositors (this is only necessary because we don't yet destroy all resources!)
             Ogre::CompositorManager::getSingleton().removeAll();
@@ -125,4 +105,7 @@
             InputManager::getInstance().leaveState("game");
         }
+
+        // disconnect all HumanPlayers
+        PlayerManager::getInstance().disconnectAllClients();
 
         if (GameMode::isMaster())
@@ -152,5 +135,5 @@
         for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); ++it)
             this->staticObjects_.insert(*it);
-        
+
         // call the loader
         COUT(0) << "Loading level..." << std::endl;
@@ -171,5 +154,5 @@
             if (find == this->staticObjects_.end())
             {
-                COUT(3) << ++i << ": " << it->getIdentifier()->getName() << " (" << *it << ")" << std::endl;
+                COUT(3) << ++i << ": " << it->getIdentifier()->getName() << " (" << *it << ')' << std::endl;
             }
         }
Index: code/branches/pickup2/src/orxonox/gamestates/GSLevel.h
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSLevel.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/GSLevel.h	(revision 6412)
@@ -52,5 +52,4 @@
         void loadLevel();
         void unloadLevel();
-        void showIngameGUI(bool show);
 
         InputState*              gameInputState_;          //!< input state for normal ingame playing
@@ -60,4 +59,5 @@
         XMLFile* startFile_;
         std::set<BaseObject*> staticObjects_;
+        bool bShowIngameGUI_;
     };
 }
Index: code/branches/pickup2/src/orxonox/gamestates/GSMainMenu.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSMainMenu.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/GSMainMenu.cc	(revision 6412)
@@ -36,4 +36,6 @@
 #include "core/Game.h"
 #include "core/ConsoleCommand.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
 #include "core/GraphicsManager.h"
 #include "core/GUIManager.h"
@@ -49,4 +51,5 @@
         , inputState_(0)
     {
+        RegisterRootObject(GSMainMenu);
         inputState_ = InputManager::getInstance().createInputState("mainMenu");
         inputState_->setMouseMode(MouseMode::Nonexclusive);
@@ -64,5 +67,5 @@
             // Load sound
             this->ambient_ = new AmbientSound(0);
-            this->ambient_->setSource("ambient/mainmenu.wav");
+            this->ambient_->setSyncMode(0x0);
         }
     }
@@ -71,5 +74,5 @@
     {
         if (GameMode::playsSound())
-            delete this->ambient_;
+            this->ambient_->destroy();
 
         InputManager::getInstance().destroyState("mainMenu");
@@ -82,6 +85,8 @@
     {
         // show main menu
-        GUIManager::getInstance().showGUI("MainMenu");
+        GUIManager::getInstance().showGUI("MainMenu", true, GraphicsManager::getInstance().isFullScreen());
         GUIManager::getInstance().setCamera(this->camera_);
+        GUIManager::getInstance().setBackground("MainMenuBackground");
+//         GUIManager::getInstance().setBackground("");
         GraphicsManager::getInstance().setCamera(this->camera_);
 
@@ -91,13 +96,17 @@
         CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSMainMenu::startDedicated), "startDedicated"));
         CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSMainMenu::startMainMenu), "startMainMenu"));
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSMainMenu::startIOConsole), "startIOConsole"));
+
+        // create command to change sound path
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSMainMenu::setMainMenuSoundPath, this), "setMMSoundPath"));
 
         KeyBinderManager::getInstance().setToDefault();
         InputManager::getInstance().enterState("mainMenu");
 
+        this->setConfigValues();
+
         if (GameMode::playsSound())
         {
-            this->ambient_->setLoop(true);
-            this->ambient_->play();
+            this->ambient_->setLooping(true);
+            this->ambient_->play(); // works without source
         }
     }
@@ -113,4 +122,6 @@
 
         GUIManager::getInstance().setCamera(0);
+        GUIManager::getInstance().setBackground("");
+        GUIManager::hideGUI("MainMenu");
         GraphicsManager::getInstance().setCamera(0);
     }
@@ -118,4 +129,29 @@
     void GSMainMenu::update(const Clock& time)
     {
+    }
+
+    void GSMainMenu::setConfigValues()
+    {
+        SetConfigValue(soundPathMain_, "mainmenu.ogg")
+            .description("Contains the path to the main menu sound file.")
+            .callback(this, &GSMainMenu::reloadSound);
+    }
+
+    void GSMainMenu::reloadSound()
+    {
+        if (GameMode::playsSound())
+        {
+            this->ambient_->setAmbientSource(soundPathMain_);
+        }
+    }
+
+    const std::string& GSMainMenu::getMainMenuSoundPath()
+    {
+        return soundPathMain_;
+    }
+
+    void GSMainMenu::setMainMenuSoundPath(const std::string& path)
+    {
+        ModifyConfigValue(soundPathMain_, set, path);
     }
 
@@ -146,5 +182,5 @@
         Game::getInstance().popState();
         Game::getInstance().popState();
-        Game::getInstance().requestStates("dedicated, level");
+        Game::getInstance().requestStates("server, level");
     }
     void GSMainMenu::startMainMenu()
@@ -155,10 +191,3 @@
         Game::getInstance().requestStates("mainmenu");
     }
-    void GSMainMenu::startIOConsole()
-    {
-        // HACK - HACK
-        Game::getInstance().popState();
-        Game::getInstance().popState();
-        Game::getInstance().requestStates("ioConsole");
-    }
 }
Index: code/branches/pickup2/src/orxonox/gamestates/GSMainMenu.h
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSMainMenu.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/GSMainMenu.h	(revision 6412)
@@ -34,8 +34,9 @@
 #include "util/OgreForwardRefs.h"
 #include "core/GameState.h"
+#include "core/OrxonoxClass.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSMainMenu : public GameState
+    class _OrxonoxExport GSMainMenu : public GameState, public OrxonoxClass
     {
     public:
@@ -46,4 +47,9 @@
         void deactivate();
         void update(const Clock& time);
+
+        void setConfigValues();
+        void reloadSound();
+        const std::string& getMainMenuSoundPath();
+        void setMainMenuSoundPath(const std::string& path);
 
         static void startStandalone();
@@ -61,4 +67,5 @@
         // ambient sound for the main menu
         AmbientSound*     ambient_;
+        std::string       soundPathMain_;
     };
 }
Index: code/branches/pickup2/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSRoot.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/GSRoot.cc	(revision 6412)
@@ -30,4 +30,5 @@
 
 #include "util/Clock.h"
+#include "core/BaseObject.h"
 #include "core/ConsoleCommand.h"
 #include "core/Game.h"
@@ -45,5 +46,4 @@
     GSRoot::GSRoot(const GameStateInfo& info)
         : GameState(info)
-        , timeFactor_(1.0f)
         , bPaused_(false)
         , timeFactorPauseBackup_(1.0f)
@@ -55,10 +55,11 @@
         NetworkFunctionBase::destroyAllNetworkFunctions();
     }
-    
+
     void GSRoot::printObjects()
     {
         unsigned int nr=0;
-        for(ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it; ++it){
-            if( dynamic_cast<Synchronisable*>(*it) )
+        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it; ++it)
+        {
+            if (dynamic_cast<Synchronisable*>(*it))
                 COUT(0) << "object: " << it->getIdentifier()->getName() << " id: " << dynamic_cast<Synchronisable*>(*it)->getObjectID() << std::endl;
             else
@@ -67,5 +68,4 @@
         }
         COUT(0) << "currently got " << nr << " objects" << std::endl;
-    
     }
 
@@ -73,5 +73,5 @@
     {
         // reset game speed to normal
-        this->timeFactor_ = 1.0f;
+        TimeFactorListener::setTimeFactor(1.0f);
 
         // time factor console command
@@ -90,13 +90,10 @@
     void GSRoot::update(const Clock& time)
     {
-        if (this->getActivity().topState)
+        for (ObjectList<Timer>::iterator it = ObjectList<Timer>::begin(); it; )
         {
-            // This state can not 'survive' on its own.
-            // Load a user interface therefore
-            Game::getInstance().requestState("ioConsole");
+            Timer* object = *it;
+            ++it;
+            object->tick(time);
         }
-
-        for (ObjectList<Timer>::iterator it = ObjectList<Timer>::begin(); it; )
-            (it++)->tick(time);
 
         /*** HACK *** HACK ***/
@@ -108,6 +105,11 @@
             leveldt = 0.0f;
         }
+        float realdt = leveldt * TimeFactorListener::getTimeFactor();
         for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; )
-            (it++)->tick(leveldt * this->timeFactor_);
+        {
+            Tickable* object = *it;
+            ++it;
+            object->tick(realdt);
+        }
         /*** HACK *** HACK ***/
     }
@@ -126,10 +128,5 @@
             if (!this->bPaused_)
             {
-                TimeFactorListener::timefactor_s = factor;
-
-                for (ObjectList<TimeFactorListener>::iterator it = ObjectList<TimeFactorListener>::begin(); it != ObjectList<TimeFactorListener>::end(); ++it)
-                    it->changedTimeFactor(factor, this->timeFactor_);
-
-                this->timeFactor_ = factor;
+                TimeFactorListener::setTimeFactor(factor);
             }
             else
@@ -144,5 +141,5 @@
             if (!this->bPaused_)
             {
-                this->timeFactorPauseBackup_ = this->timeFactor_;
+                this->timeFactorPauseBackup_ = TimeFactorListener::getTimeFactor();
                 this->setTimeFactor(0.0f);
                 this->bPaused_ = true;
@@ -155,3 +152,8 @@
         }
     }
+
+    float GSRoot::getTimeFactor()
+    {
+        return TimeFactorListener::getTimeFactor();
+    }
 }
Index: code/branches/pickup2/src/orxonox/gamestates/GSRoot.h
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSRoot.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/GSRoot.h	(revision 6412)
@@ -51,8 +51,7 @@
         void setTimeFactor(float factor);
         void pause();
-        float getTimeFactor() { return this->timeFactor_; }
+        float getTimeFactor();
 
     private:
-        float                 timeFactor_;              //!< A factor that sets the gamespeed. 1 is normal.
         bool                  bPaused_;
         float                 timeFactorPauseBackup_;
Index: code/branches/pickup2/src/orxonox/gamestates/GSServer.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gamestates/GSServer.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gamestates/GSServer.cc	(revision 6412)
@@ -30,5 +30,5 @@
 
 #include "util/Debug.h"
-#include "core/CommandLine.h"
+#include "core/CommandLineParser.h"
 #include "core/Game.h"
 #include "core/GameMode.h"
@@ -37,5 +37,5 @@
 namespace orxonox
 {
-    DeclareGameState(GSServer, "server", false, true);
+    DeclareGameState(GSServer, "server", false, false);
 
     SetCommandLineArgument(port, 55556).shortcut("p").information("Network communication port to be used 0-65535 (default: 55556)");
@@ -55,5 +55,5 @@
         GameMode::setHasServer(true);
 
-        this->server_ = new Server(CommandLine::getValue("port"));
+        this->server_ = new Server(CommandLineParser::getValue("port"));
         COUT(0) << "Loading scene in server mode" << std::endl;
 
Index: code/branches/pickup2/src/orxonox/gametypes/Asteroids.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gametypes/Asteroids.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gametypes/Asteroids.cc	(revision 6412)
@@ -72,5 +72,5 @@
         Gametype::start();
 
-        std::string message = "The match has started! Reach the first chekpoint within 15 seconds! But be aware, there may be pirates around...";
+        std::string message("The match has started! Reach the first chekpoint within 15 seconds! But be aware, there may be pirates around...");
         COUT(0) << message << std::endl;
         Host::Broadcast(message);
@@ -81,5 +81,5 @@
         Gametype::end();
 
-        std::string message = "The match has ended.";
+        std::string message("The match has ended.");
         COUT(0) << message << std::endl;
         Host::Broadcast(message);
Index: code/branches/pickup2/src/orxonox/gametypes/Deathmatch.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gametypes/Deathmatch.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gametypes/Deathmatch.cc	(revision 6412)
@@ -47,5 +47,5 @@
         Gametype::start();
 
-        std::string message = "The match has started!";
+        std::string message("The match has started!");
         COUT(0) << message << std::endl;
         Host::Broadcast(message);
@@ -56,5 +56,5 @@
         Gametype::end();
 
-        std::string message = "The match has ended.";
+        std::string message("The match has ended.");
         COUT(0) << message << std::endl;
         Host::Broadcast(message);
@@ -65,5 +65,5 @@
         Gametype::playerEntered(player);
 
-        std::string message = player->getName() + " entered the game";
+        const std::string& message = player->getName() + " entered the game";
         COUT(0) << message << std::endl;
         Host::Broadcast(message);
@@ -76,5 +76,5 @@
         if (valid_player)
         {
-            std::string message = player->getName() + " left the game";
+            const std::string& message = player->getName() + " left the game";
             COUT(0) << message << std::endl;
             Host::Broadcast(message);
@@ -90,5 +90,5 @@
         if (valid_player)
         {
-            std::string message = player->getOldName() + " changed name to " + player->getName();
+            const std::string& message = player->getOldName() + " changed name to " + player->getName();
             COUT(0) << message << std::endl;
             Host::Broadcast(message);
@@ -126,5 +126,5 @@
         if (player)
         {
-            std::string message = player->getName() + " scores!";
+            const std::string& message = player->getName() + " scores!";
             COUT(0) << message << std::endl;
             Host::Broadcast(message);
Index: code/branches/pickup2/src/orxonox/gametypes/Gametype.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gametypes/Gametype.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gametypes/Gametype.cc	(revision 6412)
@@ -51,5 +51,5 @@
     {
         RegisterObject(Gametype);
-        
+
         this->gtinfo_ = new GametypeInfo(creator);
 
@@ -71,5 +71,5 @@
 
         // load the corresponding score board
-        if (GameMode::showsGraphics() && this->scoreboardTemplate_ != "")
+        if (GameMode::showsGraphics() && !this->scoreboardTemplate_.empty())
         {
             this->scoreboard_ = new OverlayGroup(this);
@@ -79,5 +79,5 @@
         else
             this->scoreboard_ = 0;
-        
+
         /* HACK HACK HACK */
         this->hackAddBots_ = createConsoleCommand( createFunctor(&Gametype::addBots, this), "hackAddBots");
@@ -87,5 +87,5 @@
         /* HACK HACK HACK */
     }
-    
+
     Gametype::~Gametype()
     {
Index: code/branches/pickup2/src/orxonox/gametypes/Gametype.h
===================================================================
--- code/branches/pickup2/src/orxonox/gametypes/Gametype.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gametypes/Gametype.h	(revision 6412)
@@ -184,5 +184,5 @@
             // Config Values
             std::string scoreboardTemplate_;
-            
+
             /* HACK HACK HACK */
             ConsoleCommand* hackAddBots_;
Index: code/branches/pickup2/src/orxonox/gametypes/TeamDeathmatch.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gametypes/TeamDeathmatch.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gametypes/TeamDeathmatch.cc	(revision 6412)
@@ -61,5 +61,5 @@
         static std::vector<ColourValue> defaultcolours(colours, colours + sizeof(colours) / sizeof(ColourValue));
 
-        SetConfigValueVector(teamcolours_, defaultcolours);
+        SetConfigValue(teamcolours_, defaultcolours);
     }
 
Index: code/branches/pickup2/src/orxonox/gametypes/UnderAttack.cc
===================================================================
--- code/branches/pickup2/src/orxonox/gametypes/UnderAttack.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/gametypes/UnderAttack.cc	(revision 6412)
@@ -69,5 +69,5 @@
     {
         this->end(); //end gametype
-        std::string message = "Ship destroyed! Team 0 has won!";
+        std::string message("Ship destroyed! Team 0 has won!");
         COUT(0) << message << std::endl;
         Host::Broadcast(message);
@@ -152,5 +152,5 @@
                 this->gameEnded_ = true;
                 this->end();
-                std::string message = "Time is up! Team 1 has won!";
+                std::string message("Time is up! Team 1 has won!");
                 COUT(0) << message << std::endl;
                 Host::Broadcast(message);
@@ -171,5 +171,5 @@
             if ( gameTime_ <= timesequence_ && gameTime_ > 0)
             {
-                std::string message = multi_cast<std::string>(timesequence_) + " seconds left!";
+                const std::string& message = multi_cast<std::string>(timesequence_) + " seconds left!";
 /*
                 COUT(0) << message << std::endl;
Index: code/branches/pickup2/src/orxonox/graphics/Billboard.cc
===================================================================
--- code/branches/pickup2/src/orxonox/graphics/Billboard.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/graphics/Billboard.cc	(revision 6412)
@@ -42,5 +42,4 @@
         RegisterObject(Billboard);
 
-        this->material_ = "";
         this->colour_ = ColourValue::White;
 //        this->rotation_ = 0;
@@ -76,5 +75,5 @@
     void Billboard::changedMaterial()
     {
-        if (this->material_ == "")
+        if (this->material_.empty())
             return;
 
@@ -99,5 +98,5 @@
         {
 /*
-            if (this->getScene() && GameMode::showsGraphics() && (this->material_ != ""))
+            if (this->getScene() && GameMode::showsGraphics() && !this->material_.empty())
             {
                 this->billboard_.setBillboardSet(this->getScene()->getSceneManager(), this->material_, this->colour_, 1);
Index: code/branches/pickup2/src/orxonox/graphics/BlinkingBillboard.cc
===================================================================
--- code/branches/pickup2/src/orxonox/graphics/BlinkingBillboard.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/graphics/BlinkingBillboard.cc	(revision 6412)
@@ -81,5 +81,5 @@
                 this->setScale(this->amplitude_ * static_cast<float>(square(sin((6.2831853 * this->time_ + this->phase_.valueRadians()) * this->frequency_))));
             else
-                this->setScale(this->amplitude_ * static_cast<float>(sin((6.2831853 * this->time_ + this->phase_.valueRadians()) * this->frequency_)));
+                this->setScale(this->amplitude_ * static_cast<float>(fabs(sin((6.2831853 * this->time_ + this->phase_.valueRadians()) * this->frequency_))));
         }
     }
Index: code/branches/pickup2/src/orxonox/graphics/Camera.cc
===================================================================
--- code/branches/pickup2/src/orxonox/graphics/Camera.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/graphics/Camera.cc	(revision 6412)
@@ -42,4 +42,5 @@
 #include "Scene.h"
 #include "CameraManager.h"
+#include "sound/SoundManager.h"
 
 namespace orxonox
@@ -61,4 +62,5 @@
 
         this->camera_ = this->getScene()->getSceneManager()->createCamera(getUniqueNumberString());
+        this->camera_->setUserObject(this);
         this->cameraNode_ = this->getScene()->getRootSceneNode()->createChildSceneNode();
         this->attachNode(this->cameraNode_);
@@ -68,4 +70,5 @@
         this->bDrag_ = false;
         this->nearClipDistance_ = 1;
+        this->lastDtLagged_ = false;
 
         this->setSyncMode(0x0);
@@ -111,11 +114,39 @@
         {
             // this stuff here may need some adjustments
-            float coeff = std::min(1.0f, 15.0f * dt);
+            float poscoeff = 15.0f * dt / this->getTimeFactor();
+            float anglecoeff = 7.0f * dt / this->getTimeFactor();
+            // Only clamp if fps rate is actually falling. Occasional high dts should
+            // not be clamped to reducing lagging effects.
+            if (poscoeff > 1.0f)
+            {
+                if (this->lastDtLagged_)
+                    poscoeff = 1.0f;
+                else
+                    this->lastDtLagged_ = true;
+            }
+            else
+                this->lastDtLagged_ = false;
+
+            if (anglecoeff > 1.0f)
+            {
+                if (this->lastDtLagged_)
+                    anglecoeff = 1.0f;
+                else
+                    this->lastDtLagged_ = true;
+            }
+            else
+                this->lastDtLagged_ = false;
 
             Vector3 offset = this->getWorldPosition() - this->cameraNode_->_getDerivedPosition();
-            this->cameraNode_->translate(coeff * offset);
+            this->cameraNode_->translate(poscoeff * offset);
 
-            this->cameraNode_->setOrientation(Quaternion::Slerp(coeff, this->cameraNode_->_getDerivedOrientation(), this->getWorldOrientation(), true));
-            //this->cameraNode_->setOrientation(this->getWorldOrientation());
+            this->cameraNode_->setOrientation(Quaternion::Slerp(anglecoeff, this->cameraNode_->_getDerivedOrientation(), this->getWorldOrientation(), true));
+        }
+
+        // Update sound listener transformation
+        if (GameMode::playsSound() && this->bHasFocus_)
+        {
+            SoundManager::getInstance().setListenerPosition(this->getWorldPosition());
+            SoundManager::getInstance().setListenerOrientation(this->getWorldOrientation());
         }
     }
Index: code/branches/pickup2/src/orxonox/graphics/Camera.h
===================================================================
--- code/branches/pickup2/src/orxonox/graphics/Camera.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/graphics/Camera.h	(revision 6412)
@@ -34,9 +34,10 @@
 #include "util/OgreForwardRefs.h"
 #include "tools/interfaces/Tickable.h"
+#include "tools/interfaces/TimeFactorListener.h"
 #include "worldentities/StaticEntity.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport Camera : public StaticEntity, public Tickable
+    class _OrxonoxExport Camera : public StaticEntity, public Tickable, public TimeFactorListener
     {
         friend class CameraManager;
@@ -51,4 +52,7 @@
             void requestFocus();
             void releaseFocus();
+
+            inline Ogre::Camera* getOgreCamera()
+               { return this->camera_; }
 
             inline bool hasFocus()
@@ -69,4 +73,5 @@
             bool             bHasFocus_;
             bool             bDrag_;
+            bool             lastDtLagged_;
     };
 }
Index: code/branches/pickup2/src/orxonox/infos/Bot.cc
===================================================================
--- code/branches/pickup2/src/orxonox/infos/Bot.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/infos/Bot.cc	(revision 6412)
@@ -94,5 +94,5 @@
         static std::vector<std::string> defaultnames(names, names + sizeof(names) / sizeof(std::string));
 
-        SetConfigValueVector(names_, defaultnames);
+        SetConfigValue(names_, defaultnames);
     }
 }
Index: code/branches/pickup2/src/orxonox/infos/HumanPlayer.cc
===================================================================
--- code/branches/pickup2/src/orxonox/infos/HumanPlayer.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/infos/HumanPlayer.cc	(revision 6412)
@@ -35,4 +35,5 @@
 #include "network/Host.h"
 #include "controllers/HumanController.h"
+#include "controllers/NewHumanController.h"
 #include "gametypes/Gametype.h"
 #include "overlays/OverlayGroup.h"
@@ -50,5 +51,5 @@
 
         this->bHumanPlayer_ = true;
-        this->defaultController_ = Class(HumanController);
+        this->defaultController_ = Class(NewHumanController);
 
         this->humanHud_ = 0;
@@ -163,5 +164,5 @@
         if (this->isInitialized() && this->isLocalPlayer())
         {
-            if (this->getGametype() && this->getGametype()->getHUDTemplate() != "")
+            if (this->getGametype() && !this->getGametype()->getHUDTemplate().empty())
                 this->setGametypeHUDTemplate(this->getGametype()->getHUDTemplate());
             else
@@ -178,5 +179,5 @@
         }
 
-        if (this->isLocalPlayer() && this->humanHudTemplate_ != "" && GameMode::showsGraphics())
+        if (this->isLocalPlayer() && !this->humanHudTemplate_.empty() && GameMode::showsGraphics())
         {
             this->humanHud_ = new OverlayGroup(this);
@@ -194,5 +195,5 @@
         }
 
-        if (this->isLocalPlayer() && this->gametypeHudTemplate_ != "")
+        if (this->isLocalPlayer() && !this->gametypeHudTemplate_.empty())
         {
             this->gametypeHud_ = new OverlayGroup(this);
Index: code/branches/pickup2/src/orxonox/infos/PlayerInfo.cc
===================================================================
--- code/branches/pickup2/src/orxonox/infos/PlayerInfo.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/infos/PlayerInfo.cc	(revision 6412)
@@ -50,5 +50,6 @@
         this->controller_ = 0;
         this->controllableEntity_ = 0;
-        this->controllableEntityID_ = CLIENTID_UNKNOWN;
+        this->controllableEntityID_ = OBJECTID_UNKNOWN;
+        this->oldControllableEntity_ = 0;
 
         this->gtinfo_ = 0;
@@ -80,5 +81,4 @@
         registerVariable(this->name_,                 VariableDirection::ToClient, new NetworkCallback<PlayerInfo>(this, &PlayerInfo::changedName));
         registerVariable(this->controllableEntityID_, VariableDirection::ToClient, new NetworkCallback<PlayerInfo>(this, &PlayerInfo::networkcallback_changedcontrollableentityID));
-        registerVariable(this->bReadyToSpawn_,        VariableDirection::ToServer);
         registerVariable(this->gtinfoID_,             VariableDirection::ToClient, new NetworkCallback<PlayerInfo>(this, &PlayerInfo::networkcallback_changedgtinfoID));
     }
@@ -139,5 +139,8 @@
         this->controller_->setPlayer(this);
         if (this->controllableEntity_)
+        {
             this->controller_->setControllableEntity(this->controllableEntity_);
+            this->controllableEntity_->setController(this->controller_);
+        }
         this->changedController();
     }
@@ -148,4 +151,6 @@
             return;
 
+        if (this->oldControllableEntity_)
+            this->stopTemporaryControl();
         if (this->controllableEntity_)
             this->stopControl();
@@ -159,5 +164,27 @@
 
         if (this->controller_)
+        {
             this->controller_->setControllableEntity(entity);
+            this->controllableEntity_->setController(this->controller_);
+        }
+
+        this->changedControllableEntity();
+    }
+
+    void PlayerInfo::startTemporaryControl(ControllableEntity* entity)
+    {
+        if (!entity)
+            return;
+
+//         assert( this->temporaryControllableEntity_==0 );
+
+        this->oldControllableEntity_ = this->controllableEntity_;
+        this->controllableEntity_ = entity;
+        this->controllableEntityID_ = entity->getObjectID();
+
+        entity->setPlayer(this);
+
+        if (this->controller_)
+            this->controller_->setControllableEntity(entity);
 
         this->changedControllableEntity();
@@ -166,4 +193,7 @@
     void PlayerInfo::stopControl()
     {
+        if ( this->oldControllableEntity_ )
+            this->stopTemporaryControl();
+
         ControllableEntity* entity = this->controllableEntity_;
 
@@ -171,4 +201,5 @@
             return;
 
+        this->controllableEntity_->setController(0);
         this->controllableEntity_ = 0;
         this->controllableEntityID_ = OBJECTID_UNKNOWN;
@@ -177,5 +208,27 @@
             this->controller_->setControllableEntity(0);
 
-        entity->removePlayer();
+        if ( GameMode::isMaster() )
+            entity->removePlayer();
+
+        this->changedControllableEntity();
+    }
+
+    void PlayerInfo::stopTemporaryControl()
+    {
+        ControllableEntity* entity = this->controllableEntity_;
+
+        assert( this->controllableEntity_ && this->oldControllableEntity_ );
+        if( !entity || !this->oldControllableEntity_ )
+            return;
+
+        this->controllableEntity_ = this->oldControllableEntity_;
+        this->controllableEntityID_ = this->controllableEntity_->getObjectID();
+        this->oldControllableEntity_ = 0;
+
+        if ( this->controllableEntity_ && this->controller_)
+            this->controller_->setControllableEntity(this->controllableEntity_);
+
+        if ( GameMode::isMaster() )
+            entity->removePlayer();
 
         this->changedControllableEntity();
@@ -196,4 +249,5 @@
     }
 
+
     void PlayerInfo::networkcallback_changedgtinfoID()
     {
Index: code/branches/pickup2/src/orxonox/infos/PlayerInfo.h
===================================================================
--- code/branches/pickup2/src/orxonox/infos/PlayerInfo.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/infos/PlayerInfo.h	(revision 6412)
@@ -69,4 +69,6 @@
             void startControl(ControllableEntity* entity);
             void stopControl();
+            void startTemporaryControl(ControllableEntity* entity);
+            void stopTemporaryControl();
 
             inline ControllableEntity* getControllableEntity() const
@@ -96,4 +98,5 @@
             Controller* controller_;
             ControllableEntity* controllableEntity_;
+            ControllableEntity* oldControllableEntity_;
             unsigned int controllableEntityID_;
 
Index: code/branches/pickup2/src/orxonox/interfaces/RadarViewable.cc
===================================================================
--- code/branches/pickup2/src/orxonox/interfaces/RadarViewable.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/interfaces/RadarViewable.cc	(revision 6412)
@@ -51,4 +51,6 @@
         , line_(NULL)
         , LineNode_(NULL)
+        , isHumanShip_(false)
+        , bVisibility_(true)
         , radarObjectCamouflage_(0.0f)
         , radarObjectShape_(Dot)
@@ -56,7 +58,4 @@
     {
         RegisterRootObject(RadarViewable);
-
-        this->bVisibility_ = true;
-        this->isHumanShip_ = false;
 
         this->uniqueId_=getUniqueNumberString();
@@ -164,5 +163,5 @@
         if (!object)
         {
-            COUT(1) << "Assertation: Every RadarViewable has to be assigned a WorldEntity pointer!" << std::endl;
+            COUT(1) << "Assertion: Every RadarViewable has to be assigned a WorldEntity pointer!" << std::endl;
             assert(0);
         }
Index: code/branches/pickup2/src/orxonox/interfaces/Rewardable.h
===================================================================
--- code/branches/pickup2/src/orxonox/interfaces/Rewardable.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/interfaces/Rewardable.h	(revision 6412)
@@ -43,5 +43,5 @@
     @brief
         Rewardable is an Interface, that can be implemented by any object to enable it to be given as reward to a player through QuestEffects. (With the AddReward effect.)
-        
+
         It just needs to inherit form Rewardable, and implement the reward() method.
     @author
Index: code/branches/pickup2/src/orxonox/items/Engine.h
===================================================================
--- code/branches/pickup2/src/orxonox/items/Engine.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/items/Engine.h	(revision 6412)
@@ -106,6 +106,4 @@
             virtual const Vector3& getDirection() const;
 
-            void loadSound(const std::string filename);
-
         private:
             void networkcallback_shipID();
Index: code/branches/pickup2/src/orxonox/items/MultiStateEngine.cc
===================================================================
--- code/branches/pickup2/src/orxonox/items/MultiStateEngine.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/items/MultiStateEngine.cc	(revision 6412)
@@ -22,4 +22,5 @@
  *   Author:
  *      Fabian 'x3n' Landau
+ *      Reto Grieder
  *   Co-authors:
  *      ...
@@ -29,17 +30,22 @@
 #include "MultiStateEngine.h"
 
+extern "C" {
+#include <lua.h>
+}
+
+#include "util/Convert.h"
 #include "core/CoreIncludes.h"
 #include "core/GameMode.h"
+#include "core/LuaState.h"
 #include "core/XMLPort.h"
+#include "worldentities/EffectContainer.h"
 #include "worldentities/pawns/SpaceShip.h"
+#include "sound/WorldSound.h"
 
 namespace orxonox
 {
-    static const float FORWARD_EFFECT_VELOCITY_THRESHOLD = 20;
-
-    static const unsigned char STATE_ACTIVE  = 1;
-    static const unsigned char STATE_FORWARD = 2;
-    static const unsigned char STATE_BOOST   = 4;
-    static const unsigned char STATE_BRAKE   = 8;
+    static const float FORWARD_EFFECT_VELOCITY_THRESHOLD = 0;
+    static const float MAX_VELOCITY_NORMAL = 111;
+    static const float MAX_VELOCITY_BOOST = 221;
 
     CreateFactory(MultiStateEngine);
@@ -49,6 +55,22 @@
         RegisterObject(MultiStateEngine);
 
+        if (GameMode::isMaster())
+        {
+            this->defEngineSndNormal_ = new WorldSound(this);
+            this->defEngineSndBoost_  = new WorldSound(this);
+            this->defEngineSndNormal_->setLooping(true);
+            this->defEngineSndBoost_->setLooping(true);
+            this->lua_ = new LuaState();
+        }
+        else
+        {
+            this->defEngineSndBoost_ = 0;
+            this->defEngineSndNormal_ = 0;
+            this->lua_ = 0;
+        }
         this->state_ = 0;
-
+        this->oldState_ = 0;
+
+        this->setSyncMode(ObjectDirection::Bidirectional);
         this->registerVariables();
     }
@@ -56,15 +78,19 @@
     MultiStateEngine::~MultiStateEngine()
     {
-        if (this->isInitialized() && !this->getShip())
-        {
-            // We have no ship, so the effects are not attached and won't be destroyed automatically
-            for (std::list<WorldEntity*>::const_iterator it = this->activeEffects_.begin(); it != this->activeEffects_.end(); ++it)
-                (*it)->destroy();
-            for (std::list<WorldEntity*>::const_iterator it = this->forwardEffects_.begin(); it != this->forwardEffects_.end(); ++it)
-                (*it)->destroy();
-            for (std::list<WorldEntity*>::const_iterator it = this->boostEffects_.begin(); it != this->boostEffects_.end(); ++it)
-                (*it)->destroy();
-            for (std::list<WorldEntity*>::const_iterator it = this->brakeEffects_.begin(); it != this->brakeEffects_.end(); ++it)
-                (*it)->destroy();
+        if (this->isInitialized())
+        {
+            if (!this->getShip())
+            {
+                // We have no ship, so the effects are not attached and won't be destroyed automatically
+                for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
+                    for (std::vector<WorldEntity*>::const_iterator it2 = (*it)->getEffectsBegin(); it2 != (*it)->getEffectsBegin(); ++it2)
+                        (*it2)->destroy();
+                if (this->defEngineSndNormal_)
+                    this->defEngineSndNormal_->destroy();
+                if (this->defEngineSndBoost_)
+                    this->defEngineSndBoost_->destroy();
+            }
+            if (this->lua_)
+                delete this->lua_;
         }
     }
@@ -73,9 +99,7 @@
     {
         SUPER(MultiStateEngine, XMLPort, xmlelement, mode);
-
-        XMLPortObject(MultiStateEngine, WorldEntity, "active",  addActiveEffect,  getActiveEffect,  xmlelement, mode);
-        XMLPortObject(MultiStateEngine, WorldEntity, "forward", addForwardEffect, getForwardEffect, xmlelement, mode);
-        XMLPortObject(MultiStateEngine, WorldEntity, "boost",   addBoostEffect,   getBoostEffect,   xmlelement, mode);
-        XMLPortObject(MultiStateEngine, WorldEntity, "brake",   addBrakeEffect,   getBrakeEffect,   xmlelement, mode);
+        XMLPortObject(MultiStateEngine, EffectContainer, "",  addEffectContainer,  getEffectContainer,  xmlelement, mode);
+        XMLPortParam(MultiStateEngine, "defEngineSndNormal",  setDefEngSndNormal,  getDefEngSndNormal,  xmlelement, mode);
+        XMLPortParam(MultiStateEngine, "defEngineSndBoost",  setDefEngSndBoost,  getDefEngSndBoost,  xmlelement, mode);
     }
 
@@ -89,47 +113,66 @@
         if (this->getShip())
         {
+            const Vector3& velocity = this->getShip()->getLocalVelocity();
+
             if (this->getShip()->hasLocalController())
             {
-                this->setSyncMode(ObjectDirection::Bidirectional);
-
                 const Vector3& direction = this->getDirection();
-                const Vector3& velocity = this->getShip()->getLocalVelocity();
-
-                bool forward = (direction.z < 0 && velocity.z < -FORWARD_EFFECT_VELOCITY_THRESHOLD);
-                bool boost = (this->getShip()->getBoost() && forward);
-                bool brake = (direction.z > 0 && velocity.z < 0);
-                bool active = (direction != Vector3::ZERO && !brake);
-
-                if (active)
-                    this->state_ |= STATE_ACTIVE;
+                bool forward = (direction.z < 0.0 && velocity.z < -FORWARD_EFFECT_VELOCITY_THRESHOLD);
+
+                this->state_ = 0;
+                if (this->getShip()->getBoost() && forward)
+                    this->state_ = Boost;
+                else if (forward && !this->state_) // this->state_ == Boost
+                    this->state_ = Normal;
+                else if (direction.z > 0.0 && velocity.z < 0.0)
+                    this->state_ = Brake;
                 else
-                    this->state_ &= ~STATE_ACTIVE;
-
-                if (forward)
-                    this->state_ |= STATE_FORWARD;
-                else
-                    this->state_ &= ~STATE_FORWARD;
-
-                if (boost)
-                    this->state_ |= STATE_BOOST;
-                else
-                    this->state_ &= ~STATE_BOOST;
-
-                if (brake)
-                    this->state_ |= STATE_BRAKE;
-                else
-                    this->state_ &= ~STATE_BRAKE;
+                    this->state_ = Idle;
             }
 
             if (GameMode::isMaster())
             {
-                for (std::list<WorldEntity*>::const_iterator it = this->activeEffects_.begin(); it != this->activeEffects_.end(); ++it)
-                    (*it)->setMainState(this->state_ & STATE_ACTIVE);
-                for (std::list<WorldEntity*>::const_iterator it = this->forwardEffects_.begin(); it != this->forwardEffects_.end(); ++it)
-                    (*it)->setMainState(this->state_ & STATE_FORWARD);
-                for (std::list<WorldEntity*>::const_iterator it = this->boostEffects_.begin(); it != this->boostEffects_.end(); ++it)
-                    (*it)->setMainState(this->state_ & STATE_BOOST);
-                for (std::list<WorldEntity*>::const_iterator it = this->brakeEffects_.begin(); it != this->brakeEffects_.end(); ++it)
-                    (*it)->setMainState(this->state_ & STATE_BRAKE);
+                int changes = this->state_ | this->oldState_;
+
+                float pitch = velocity.length();
+                if (this->state_ & Normal)
+                    defEngineSndNormal_->setPitch(clamp(pitch/MAX_VELOCITY_NORMAL + 1, 0.5f, 2.0f));
+                if (this->state_ & Boost)
+                    defEngineSndBoost_->setPitch(clamp(pitch/MAX_VELOCITY_BOOST + 1, 0.5f, 2.0f));
+
+                if (changes & Idle)
+                {
+                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Idle);
+                    lua_setglobal(this->lua_->getInternalLuaState(), "idle");
+                }
+                if (changes & Normal)
+                {
+                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Normal);
+                    lua_setglobal(this->lua_->getInternalLuaState(), "normal");
+                    if (this->state_ & Normal)
+                        defEngineSndNormal_->play();
+                    else
+                        defEngineSndNormal_->stop();
+                }
+                if (changes & Brake)
+                {
+                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Brake);
+                    lua_setglobal(this->lua_->getInternalLuaState(), "brake");
+                }
+                if (changes & Boost)
+                {
+                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Boost);
+                    lua_setglobal(this->lua_->getInternalLuaState(), "boost");
+                    if (this->state_ & Boost)
+                        defEngineSndBoost_->play();
+                    else
+                        defEngineSndBoost_->stop();
+                }
+
+                this->oldState_ = this->state_;
+
+                // Update all effect conditions
+                for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
+                    (*it)->updateCondition();
             }
         }
@@ -145,88 +188,70 @@
             return;
 
-        for (std::list<WorldEntity*>::const_iterator it = this->activeEffects_.begin(); it != this->activeEffects_.end(); ++it)
-            ship->attach(*it);
-        for (std::list<WorldEntity*>::const_iterator it = this->forwardEffects_.begin(); it != this->forwardEffects_.end(); ++it)
-            ship->attach(*it);
-        for (std::list<WorldEntity*>::const_iterator it = this->boostEffects_.begin(); it != this->boostEffects_.end(); ++it)
-            ship->attach(*it);
-        for (std::list<WorldEntity*>::const_iterator it = this->brakeEffects_.begin(); it != this->brakeEffects_.end(); ++it)
-            ship->attach(*it);
-    }
-
-    void MultiStateEngine::addActiveEffect(WorldEntity* effect)
-    {
-        this->activeEffects_.push_back(effect);
+        if( this->defEngineSndNormal_ )
+            this->getShip()->attach(defEngineSndNormal_);
+        if( this->defEngineSndBoost_ )
+            this->getShip()->attach(defEngineSndBoost_);
+
+        for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
+            for (std::vector<WorldEntity*>::const_iterator it2 = (*it)->getEffectsBegin(); it2 != (*it)->getEffectsEnd(); ++it2)
+                this->getShip()->attach(*it2);
+    }
+
+    void MultiStateEngine::addEffectContainer(EffectContainer* effect)
+    {
+        if (effect == NULL)
+            return;
+        effect->setLuaState(this->lua_, 'f' + multi_cast<std::string>(this->effectContainers_.size()));
+        this->effectContainers_.push_back(effect);
         if (this->getShip())
-            this->getShip()->attach(effect);
-    }
-
-    void MultiStateEngine::addForwardEffect(WorldEntity* effect)
-    {
-        this->forwardEffects_.push_back(effect);
-        if (this->getShip())
-            this->getShip()->attach(effect);
-    }
-
-    void MultiStateEngine::addBoostEffect(WorldEntity* effect)
-    {
-        this->boostEffects_.push_back(effect);
-        if (this->getShip())
-            this->getShip()->attach(effect);
-    }
-
-    void MultiStateEngine::addBrakeEffect(WorldEntity* effect)
-    {
-        this->brakeEffects_.push_back(effect);
-        if (this->getShip())
-            this->getShip()->attach(effect);
-    }
-
-    WorldEntity* MultiStateEngine::getActiveEffect(unsigned int index) const
+        {
+            for (std::vector<WorldEntity*>::const_iterator it = effect->getEffectsBegin(); it != effect->getEffectsBegin(); ++it)
+                this->getShip()->attach(*it);
+        }
+    }
+
+    EffectContainer* MultiStateEngine::getEffectContainer(unsigned int index) const
     {
         unsigned int i = 0;
-        for (std::list<WorldEntity*>::const_iterator it = this->activeEffects_.begin(); it != this->activeEffects_.end(); ++it)
+        for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
         {
             if (i == index)
                 return (*it);
-            ++i;
-        }
-        return 0;
-    }
-
-    WorldEntity* MultiStateEngine::getForwardEffect(unsigned int index) const
-    {
-        unsigned int i = 0;
-        for (std::list<WorldEntity*>::const_iterator it = this->forwardEffects_.begin(); it != this->forwardEffects_.end(); ++it)
-        {
-            if (i == index)
-                return (*it);
-            ++i;
-        }
-        return 0;
-    }
-
-    WorldEntity* MultiStateEngine::getBoostEffect(unsigned int index) const
-    {
-        unsigned int i = 0;
-        for (std::list<WorldEntity*>::const_iterator it = this->boostEffects_.begin(); it != this->boostEffects_.end(); ++it)
-        {
-            if (i == index)
-                return (*it);
-            ++i;
-        }
-        return 0;
-    }
-
-    WorldEntity* MultiStateEngine::getBrakeEffect(unsigned int index) const
-    {
-        unsigned int i = 0;
-        for (std::list<WorldEntity*>::const_iterator it = this->brakeEffects_.begin(); it != this->brakeEffects_.end(); ++it)
-        {
-            if (i == index)
-                return (*it);
-            ++i;
-        }
-        return 0;
+        }
+        return NULL;
+    }
+
+    void MultiStateEngine::setDefEngSndNormal(const std::string &engineSound)
+    {
+        if( defEngineSndNormal_ )
+            defEngineSndNormal_->setSource(engineSound);
+        else
+            assert(0); // This should never happen, because soundpointer is only available on master
+    }
+
+    const std::string& MultiStateEngine::getDefEngSndNormal()
+    {
+        if( defEngineSndNormal_ )
+            return defEngineSndNormal_->getSource();
+        else
+            assert(0);
+        return BLANKSTRING;
+    }
+
+    void MultiStateEngine::setDefEngSndBoost(const std::string &engineSound)
+    {
+        if( defEngineSndBoost_ )
+            defEngineSndBoost_->setSource(engineSound);
+        else
+            assert(0);
+    }
+
+    const std::string& MultiStateEngine::getDefEngSndBoost()
+    {
+        if( this->defEngineSndBoost_ )
+            return defEngineSndBoost_->getSource();
+        else
+            assert(0);
+        return BLANKSTRING;
     }
 }
Index: code/branches/pickup2/src/orxonox/items/MultiStateEngine.h
===================================================================
--- code/branches/pickup2/src/orxonox/items/MultiStateEngine.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/items/MultiStateEngine.h	(revision 6412)
@@ -22,4 +22,5 @@
  *   Author:
  *      Fabian 'x3n' Landau
+ *      Reto Grieder
  *   Co-authors:
  *      ...
@@ -32,5 +33,5 @@
 #include "OrxonoxPrereqs.h"
 
-#include <list>
+#include <vector>
 #include "Engine.h"
 
@@ -40,4 +41,12 @@
     {
         public:
+            enum EngineState
+            {
+                Idle    = 1,
+                Normal  = 2,
+                Brake   = 4,
+                Boost   = 8
+            };
+
             MultiStateEngine(BaseObject* creator);
             virtual ~MultiStateEngine();
@@ -50,20 +59,19 @@
             virtual void addToSpaceShip(SpaceShip* ship);
 
-            void addActiveEffect(WorldEntity* effect);
-            void addForwardEffect(WorldEntity* effect);
-            void addBoostEffect(WorldEntity* effect);
-            void addBrakeEffect(WorldEntity* effect);
+            void addEffectContainer(EffectContainer* effect);
+            EffectContainer* getEffectContainer(unsigned int index) const;
 
-            WorldEntity* getActiveEffect(unsigned int index) const;
-            WorldEntity* getForwardEffect(unsigned int index) const;
-            WorldEntity* getBoostEffect(unsigned int index) const;
-            WorldEntity* getBrakeEffect(unsigned int index) const;
+            void setDefEngSndNormal(const std::string& engineSound);
+            const std::string& getDefEngSndNormal();
+            void setDefEngSndBoost(const std::string& engineSound);
+            const std::string& getDefEngSndBoost();
 
         private:
-            unsigned char state_;
-            std::list<WorldEntity*> activeEffects_;
-            std::list<WorldEntity*> forwardEffects_;
-            std::list<WorldEntity*> boostEffects_;
-            std::list<WorldEntity*> brakeEffects_;
+            int state_;
+            int oldState_;
+            LuaState* lua_;
+            std::vector<EffectContainer*> effectContainers_;
+            WorldSound* defEngineSndNormal_;
+            WorldSound* defEngineSndBoost_;
     };
 }
Index: code/branches/pickup2/src/orxonox/overlays/InGameConsole.cc
===================================================================
--- code/branches/pickup2/src/orxonox/overlays/InGameConsole.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/overlays/InGameConsole.cc	(revision 6412)
@@ -44,5 +44,5 @@
 #include "util/Convert.h"
 #include "util/Math.h"
-#include "util/UTFStringConversions.h"
+#include "util/DisplayStringConversions.h"
 #include "core/CoreIncludes.h"
 #include "core/ConfigValueIncludes.h"
@@ -61,5 +61,4 @@
     SetConsoleCommand(InGameConsole, closeConsole, true);
 
-    InGameConsole* InGameConsole::singletonPtr_s = 0;
     ManageScopedSingleton(InGameConsole, ScopeID::Graphics, false);
 
@@ -68,5 +67,7 @@
     */
     InGameConsole::InGameConsole()
-        : consoleOverlay_(0)
+        : shell_(new Shell("InGameConsole", true))
+        , bShowCursor_(false)
+        , consoleOverlay_(0)
         , consoleOverlayContainer_(0)
         , consoleOverlayNoise_(0)
@@ -99,4 +100,7 @@
         // destroy the input state previously created (InputBuffer gets destroyed by the Shell)
         InputManager::getInstance().destroyState("console");
+
+        // destroy the underlaying shell
+        this->shell_->destroy();
 
         Ogre::OverlayManager* ovMan = Ogre::OverlayManager::getSingletonPtr();
@@ -174,5 +178,5 @@
         // create the corresponding input state
         inputState_ = InputManager::getInstance().createInputState("console", false, false, InputStatePriority::Console);
-        inputState_->setKeyHandler(Shell::getInstance().getInputBuffer());
+        inputState_->setKeyHandler(this->shell_->getInputBuffer());
         bHidesAllInputChanged();
 
@@ -214,4 +218,12 @@
         font->addCodePointRange(Ogre::Font::CodePointRange(161, 255));
 
+        // create noise
+        this->consoleOverlayNoise_ = static_cast<Ogre::PanelOverlayElement*>(ovMan->createOverlayElement("Panel", "InGameConsoleNoise"));
+        this->consoleOverlayNoise_->setMetricsMode(Ogre::GMM_PIXELS);
+        this->consoleOverlayNoise_->setPosition(5,0);
+        this->consoleOverlayNoise_->setMaterialName("ConsoleNoiseSmall");
+        // comment following line to disable noise
+        this->consoleOverlayBorder_->addChild(this->consoleOverlayNoise_);
+
         // create the text lines
         this->consoleOverlayTextAreas_ = new Ogre::TextAreaOverlayElement*[LINES];
@@ -225,5 +237,5 @@
             this->consoleOverlayTextAreas_[i]->setLeft(8);
             this->consoleOverlayTextAreas_[i]->setCaption("");
-            this->consoleOverlayContainer_->addChild(this->consoleOverlayTextAreas_[i]);
+            this->consoleOverlayNoise_->addChild(this->consoleOverlayTextAreas_[i]);
         }
 
@@ -236,21 +248,11 @@
         this->consoleOverlayCursor_->setLeft(7);
         this->consoleOverlayCursor_->setCaption(std::string(this->cursorSymbol_, 1));
-        this->consoleOverlayContainer_->addChild(this->consoleOverlayCursor_);
-
-        // create noise
-        this->consoleOverlayNoise_ = static_cast<Ogre::PanelOverlayElement*>(ovMan->createOverlayElement("Panel", "InGameConsoleNoise"));
-        this->consoleOverlayNoise_->setMetricsMode(Ogre::GMM_PIXELS);
-        this->consoleOverlayNoise_->setPosition(5,0);
-        this->consoleOverlayNoise_->setMaterialName("ConsoleNoiseSmall");
-        // comment following line to disable noise
-        this->consoleOverlayContainer_->addChild(this->consoleOverlayNoise_);
+        this->consoleOverlayNoise_->addChild(this->consoleOverlayCursor_);
 
         this->windowResized(this->getWindowWidth(), this->getWindowWidth());
 
         // move overlay "above" the top edge of the screen
-        // we take -1.2 because the border makes the panel bigger
-        this->consoleOverlayContainer_->setTop(-1.2 * this->relativeHeight);
-
-        Shell::getInstance().addOutputLevel(true);
+        // we take -1.3 because the border makes the panel bigger
+        this->consoleOverlayContainer_->setTop(-1.3 * this->relativeHeight);
 
         COUT(4) << "Info: InGameConsole initialized" << std::endl;
@@ -266,9 +268,9 @@
     void InGameConsole::linesChanged()
     {
-        std::list<std::string>::const_iterator it = Shell::getInstance().getNewestLineIterator();
+        Shell::LineList::const_iterator it = this->shell_->getNewestLineIterator();
         int max = 0;
         for (int i = 1; i < LINES; ++i)
         {
-            if (it != Shell::getInstance().getEndIterator())
+            if (it != this->shell_->getEndIterator())
             {
                 ++it;
@@ -280,10 +282,10 @@
 
         for (int i = LINES - 1; i > max; --i)
-            this->print("", i, true);
+            this->print("", Shell::None, i, true);
 
         for (int i = max; i >= 1; --i)
         {
             --it;
-            this->print(*it, i, true);
+            this->print(it->first, it->second, i, true);
         }
     }
@@ -295,5 +297,5 @@
     {
         if (LINES > 1)
-            this->print(*Shell::getInstance().getNewestLineIterator(), 1);
+            this->print(this->shell_->getNewestLineIterator()->first, this->shell_->getNewestLineIterator()->second, 1);
     }
 
@@ -314,7 +316,7 @@
     {
         if (LINES > 0)
-            this->print(Shell::getInstance().getInput(), 0);
-
-        if (Shell::getInstance().getInput() == "" || Shell::getInstance().getInput().size() == 0)
+            this->print(this->shell_->getInput(), Shell::Input, 0);
+
+        if (this->shell_->getInput().empty())
             this->inputWindowStart_ = 0;
     }
@@ -325,5 +327,5 @@
     void InGameConsole::cursorChanged()
     {
-        unsigned int pos = Shell::getInstance().getCursorPosition() - inputWindowStart_;
+        unsigned int pos = this->shell_->getCursorPosition() - inputWindowStart_;
         if (pos > maxCharsPerLine_)
             pos = maxCharsPerLine_;
@@ -331,4 +333,12 @@
         this->consoleOverlayCursor_->setCaption(std::string(pos,' ') + cursorSymbol_);
         this->consoleOverlayCursor_->setTop(static_cast<int>(this->windowH_ * this->relativeHeight) - 24);
+    }
+
+    /**
+        @brief Called if a command is about to be executed
+    */
+    void InGameConsole::executed()
+    {
+        this->shell_->addOutput(this->shell_->getInput() + '\n', Shell::Command);
     }
 
@@ -348,5 +358,5 @@
         @brief Used to control the actual scrolling and the cursor.
     */
-    void InGameConsole::update(const Clock& time)
+    void InGameConsole::preUpdate(const Clock& time)
     {
         if (this->scroll_ != 0)
@@ -374,9 +384,9 @@
                 // scrolling up
                 // note: +0.01 for the same reason as when scrolling down
-                float deltaScroll = (1.2 * this->relativeHeight + 0.01 + oldTop) * time.getDeltaTime() * this->scrollSpeed_;
-                if (oldTop - deltaScroll <= -1.2 * this->relativeHeight)
+                float deltaScroll = (1.3 * this->relativeHeight + 0.01 + oldTop) * time.getDeltaTime() * this->scrollSpeed_;
+                if (oldTop - deltaScroll <= -1.3 * this->relativeHeight)
                 {
                     // window has completely scrolled up
-                    this->consoleOverlayContainer_->setTop(-1.2 * this->relativeHeight);
+                    this->consoleOverlayContainer_->setTop(-1.3 * this->relativeHeight);
                     this->scroll_ = 0;
                     this->consoleOverlay_->hide();
@@ -446,18 +456,10 @@
         @param s String to be printed
     */
-    void InGameConsole::print(const std::string& text, int index, bool alwaysShift)
-    {
-        char level = 0;
-        if (text.size() > 0)
-            level = text[0];
-
+    void InGameConsole::print(const std::string& text, Shell::LineType type, int index, bool alwaysShift)
+    {
         std::string output = text;
-
-        if (level >= -1 && level <= 5)
-            output.erase(0, 1);
-
         if (LINES > index)
         {
-            this->colourLine(level, index);
+            this->colourLine(type, index);
 
             if (index > 0)
@@ -467,12 +469,12 @@
                 {
                     ++linesUsed;
-                    this->consoleOverlayTextAreas_[index]->setCaption(multi_cast<Ogre::UTFString>(output.substr(0, this->maxCharsPerLine_)));
+                    this->consoleOverlayTextAreas_[index]->setCaption(multi_cast<Ogre::DisplayString>(output.substr(0, this->maxCharsPerLine_)));
                     output.erase(0, this->maxCharsPerLine_);
                     output.insert(0, 1, ' ');
                     if (linesUsed > numLinesShifted_ || alwaysShift)
                         this->shiftLines();
-                    this->colourLine(level, index);
+                    this->colourLine(type, index);
                 }
-                this->consoleOverlayTextAreas_[index]->setCaption(multi_cast<Ogre::UTFString>(output));
+                this->consoleOverlayTextAreas_[index]->setCaption(multi_cast<Ogre::DisplayString>(output));
                 this->displayedText_ = output;
                 this->numLinesShifted_ = linesUsed;
@@ -482,8 +484,8 @@
                 if (output.size() > this->maxCharsPerLine_)
                 {
-                    if (Shell::getInstance().getInputBuffer()->getCursorPosition() < this->inputWindowStart_)
-                        this->inputWindowStart_ = Shell::getInstance().getInputBuffer()->getCursorPosition();
-                    else if (Shell::getInstance().getInputBuffer()->getCursorPosition() >= (this->inputWindowStart_ + this->maxCharsPerLine_ - 1))
-                        this->inputWindowStart_ = Shell::getInstance().getInputBuffer()->getCursorPosition() - this->maxCharsPerLine_ + 1;
+                    if (this->shell_->getInputBuffer()->getCursorPosition() < this->inputWindowStart_)
+                        this->inputWindowStart_ = this->shell_->getInputBuffer()->getCursorPosition();
+                    else if (this->shell_->getInputBuffer()->getCursorPosition() >= (this->inputWindowStart_ + this->maxCharsPerLine_ - 1))
+                        this->inputWindowStart_ = this->shell_->getInputBuffer()->getCursorPosition() - this->maxCharsPerLine_ + 1;
 
                     output = output.substr(this->inputWindowStart_, this->maxCharsPerLine_);
@@ -492,5 +494,5 @@
                   this->inputWindowStart_ = 0;
                 this->displayedText_ = output;
-                this->consoleOverlayTextAreas_[index]->setCaption(multi_cast<Ogre::UTFString>(output));
+                this->consoleOverlayTextAreas_[index]->setCaption(multi_cast<Ogre::DisplayString>(output));
             }
         }
@@ -506,5 +508,5 @@
             this->bActive_ = true;
             InputManager::getInstance().enterState("console");
-            Shell::getInstance().registerListener(this);
+            this->shell_->registerListener(this);
 
             this->windowResized(this->windowW_, this->windowH_);
@@ -528,5 +530,5 @@
             this->bActive_ = false;
             InputManager::getInstance().leaveState("console");
-            Shell::getInstance().unregisterListener(this);
+            this->shell_->unregisterListener(this);
 
             // scroll up
@@ -549,46 +551,44 @@
     }
 
-    void InGameConsole::colourLine(int colourcode, int index)
-    {
-        if (colourcode == -1)
-        {
-            this->consoleOverlayTextAreas_[index]->setColourTop   (ColourValue(0.90, 0.90, 0.90, 1.00));
-            this->consoleOverlayTextAreas_[index]->setColourBottom(ColourValue(1.00, 1.00, 1.00, 1.00));
-        }
-        else if (colourcode == 1)
-        {
-            this->consoleOverlayTextAreas_[index]->setColourTop   (ColourValue(0.95, 0.25, 0.25, 1.00));
-            this->consoleOverlayTextAreas_[index]->setColourBottom(ColourValue(1.00, 0.50, 0.50, 1.00));
-        }
-        else if (colourcode == 2)
-        {
-            this->consoleOverlayTextAreas_[index]->setColourTop   (ColourValue(0.95, 0.50, 0.20, 1.00));
-            this->consoleOverlayTextAreas_[index]->setColourBottom(ColourValue(1.00, 0.70, 0.50, 1.00));
-        }
-        else if (colourcode == 3)
-        {
-            this->consoleOverlayTextAreas_[index]->setColourTop   (ColourValue(0.50, 0.50, 0.95, 1.00));
-            this->consoleOverlayTextAreas_[index]->setColourBottom(ColourValue(0.80, 0.80, 1.00, 1.00));
-        }
-        else if (colourcode == 4)
-        {
-            this->consoleOverlayTextAreas_[index]->setColourTop   (ColourValue(0.65, 0.48, 0.44, 1.00));
-            this->consoleOverlayTextAreas_[index]->setColourBottom(ColourValue(1.00, 0.90, 0.90, 1.00));
-        }
-        else if (colourcode == 5)
-        {
-            this->consoleOverlayTextAreas_[index]->setColourTop   (ColourValue(0.40, 0.20, 0.40, 1.00));
-            this->consoleOverlayTextAreas_[index]->setColourBottom(ColourValue(0.80, 0.60, 0.80, 1.00));
-        }
-        else
-        {
-            this->consoleOverlayTextAreas_[index]->setColourTop   (ColourValue(0.21, 0.69, 0.21, 1.00));
-            this->consoleOverlayTextAreas_[index]->setColourBottom(ColourValue(0.80, 1.00, 0.80, 1.00));
-        }
-    }
-
-    // ###############################
-    // ###      satic methods      ###
-    // ###############################
+    void InGameConsole::colourLine(Shell::LineType type, int index)
+    {
+        ColourValue colourTop, colourBottom;
+        switch (type)
+        {
+        case Shell::Error:   colourTop = ColourValue(0.95, 0.25, 0.25, 1.00);
+                          colourBottom = ColourValue(1.00, 0.50, 0.50, 1.00); break;
+
+        case Shell::Warning: colourTop = ColourValue(0.95, 0.50, 0.20, 1.00);
+                          colourBottom = ColourValue(1.00, 0.70, 0.50, 1.00); break;
+
+        case Shell::Info:    colourTop = ColourValue(0.50, 0.50, 0.95, 1.00);
+                          colourBottom = ColourValue(0.80, 0.80, 1.00, 1.00); break;
+
+        case Shell::Debug:   colourTop = ColourValue(0.65, 0.48, 0.44, 1.00);
+                          colourBottom = ColourValue(1.00, 0.90, 0.90, 1.00); break;
+
+        case Shell::Verbose: colourTop = ColourValue(0.40, 0.20, 0.40, 1.00);
+                          colourBottom = ColourValue(0.80, 0.60, 0.80, 1.00); break;
+
+        case Shell::Ultra:   colourTop = ColourValue(0.21, 0.69, 0.21, 1.00);
+                          colourBottom = ColourValue(0.80, 1.00, 0.80, 1.00); break;
+
+        case Shell::Command: colourTop = ColourValue(0.80, 0.80, 0.80, 1.00);
+                          colourBottom = ColourValue(0.90, 0.90, 0.90, 0.90); break;
+
+        case Shell::Hint:    colourTop = ColourValue(0.80, 0.80, 0.80, 1.00);
+                          colourBottom = ColourValue(0.90, 0.90, 0.90, 1.00); break;
+
+        default:             colourTop = ColourValue(0.90, 0.90, 0.90, 1.00);
+                          colourBottom = ColourValue(1.00, 1.00, 1.00, 1.00); break;
+        }
+
+        this->consoleOverlayTextAreas_[index]->setColourTop   (colourTop);
+        this->consoleOverlayTextAreas_[index]->setColourBottom(colourBottom);
+    }
+
+    // ################################
+    // ###      static methods      ###
+    // ################################
 
     /**
Index: code/branches/pickup2/src/orxonox/overlays/InGameConsole.h
===================================================================
--- code/branches/pickup2/src/orxonox/overlays/InGameConsole.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/overlays/InGameConsole.h	(revision 6412)
@@ -52,5 +52,5 @@
         void setConfigValues();
 
-        void update(const Clock& time);
+        void preUpdate(const Clock& time);
 
         static void openConsole();
@@ -68,10 +68,11 @@
         void inputChanged();
         void cursorChanged();
+        void executed();
         void exit();
 
         void shiftLines();
-        void colourLine(int colourcode, int index);
+        void colourLine(Shell::LineType type, int index);
         void setCursorPosition(unsigned int pos);
-        void print(const std::string& text, int index, bool alwaysShift = false);
+        void print(const std::string& text, Shell::LineType type, int index, bool alwaysShift = false);
 
         void windowResized(unsigned int newWidth, unsigned int newHeight);
@@ -81,4 +82,5 @@
 
     private: // variables
+        Shell* shell_;
         bool bActive_;
         int windowW_;
Index: code/branches/pickup2/src/orxonox/overlays/Map.cc
===================================================================
--- code/branches/pickup2/src/orxonox/overlays/Map.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/overlays/Map.cc	(revision 6412)
@@ -49,4 +49,5 @@
 #include <OgreViewport.h>
 
+#include "util/StringUtils.h"
 #include "core/ConsoleCommand.h"
 #include "core/CoreIncludes.h"
@@ -94,9 +95,6 @@
 
         //Getting Scene Manager (Hack)
-        if( !sManager_ )
-        {
-            ObjectList<Scene>::iterator it = ObjectList<Scene>::begin();
-            this->sManager_ = it->getSceneManager();
-        }
+        ObjectList<Scene>::iterator it = ObjectList<Scene>::begin();
+        this->sManager_ = it->getSceneManager();
         if( !Map::getMapSceneManager() )
         {
Index: code/branches/pickup2/src/orxonox/overlays/OrxonoxOverlay.cc
===================================================================
--- code/branches/pickup2/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 6412)
@@ -39,12 +39,16 @@
 #include <OgrePanelOverlayElement.h>
 #include <OgreRenderWindow.h>
+#include <OgreMaterialManager.h>
+#include <OgreTechnique.h>
+#include <OgrePass.h>
 
 #include "util/Convert.h"
 #include "util/Exception.h"
-#include "util/StringUtils.h"
 #include "core/GameMode.h"
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
 #include "core/ConsoleCommand.h"
+
+#include "OverlayGroup.h"
 
 namespace orxonox
@@ -81,13 +85,13 @@
         // Get aspect ratio from the render window. Later on, we get informed automatically
         this->windowAspectRatio_ = static_cast<float>(this->getWindowWidth()) / this->getWindowHeight();
-        this->sizeCorrectionChanged();
-
-        this->changedVisibility();
-
-        setSize(Vector2(1.0f, 1.0f));
-        setPickPoint(Vector2(0.0f, 0.0f));
-        setPosition(Vector2(0.0f, 0.0f));
-        setRotation(Degree(0.0));
-        setAspectCorrection(false);
+
+        this->size_ = Vector2(1.0f, 1.0f);
+        this->pickPoint_= Vector2(0.0f, 0.0f);
+        this->position_ = Vector2(0.0f, 0.0f);
+        this->angle_ = Degree(0.0);
+        this->bCorrectAspect_ = false;
+        this->rotState_ = Horizontal;
+        this->angleChanged(); // updates all other values as well
+
         setBackgroundMaterial("");
     }
@@ -141,5 +145,5 @@
 
         if (OrxonoxOverlay::overlays_s.find(this->getName()) != OrxonoxOverlay::overlays_s.end())
-            COUT(1) << "Overlay names should be unique or you cannnot access them via console. Name: \"" << this->getName() << "\"" << std::endl;
+            COUT(1) << "Overlay names should be unique or you cannnot access them via console. Name: \"" << this->getName() << '"' << std::endl;
 
         OrxonoxOverlay::overlays_s[this->getName()] = this;
@@ -149,5 +153,5 @@
     void OrxonoxOverlay::setBackgroundMaterial(const std::string& material)
     {
-        if (this->background_ && material != "")
+        if (this->background_ && !material.empty())
             this->background_->setMaterialName(material);
     }
@@ -165,8 +169,11 @@
     void OrxonoxOverlay::changedVisibility()
     {
+        SUPER( OrxonoxOverlay, changedVisibility );
+
         if (!this->overlay_)
             return;
 
-        if (this->isVisible())
+        // only set to visible if corresponding OverlayGroup is also visible
+        if (this->isVisible() && (!this->getOverlayGroup() || this->getOverlayGroup()->isVisible()) )
             this->overlay_->show();
         else
@@ -304,5 +311,5 @@
         std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
         if (it != overlays_s.end())
-            (*it).second->scale(Vector2(scale, scale));
+            it->second->scale(Vector2(scale, scale));
     }
 
@@ -319,5 +326,5 @@
         if (it != overlays_s.end())
         {
-            OrxonoxOverlay* overlay= (*it).second;
+            OrxonoxOverlay* overlay= it->second;
             if(overlay->isVisible())
                 overlay->hide();
@@ -338,5 +345,5 @@
         std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
         if (it != overlays_s.end())
-            (*it).second->scroll(scroll);
+            it->second->scroll(scroll);
     }
 
@@ -352,5 +359,22 @@
         std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
         if (it != overlays_s.end())
-            (*it).second->rotate(angle);
+            it->second->rotate(angle);
+    }
+
+    void OrxonoxOverlay::setOverlayGroup(OverlayGroup* group)
+    {
+        if (group != this->group_)
+        {
+            if (this->group_)
+                this->group_->removeElement(this);
+            this->group_ = group;
+            this->changedOverlayGroup();
+        }
+    }
+
+    void OrxonoxOverlay::setBackgroundAlpha(float alpha) {
+        Ogre::MaterialPtr ptr = this->background_->getMaterial();
+        Ogre::TextureUnitState* tempTx = ptr->getTechnique(0)->getPass(0)->getTextureUnitState(0);
+        tempTx->setAlphaOperation(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, alpha);
     }
 }
Index: code/branches/pickup2/src/orxonox/overlays/OrxonoxOverlay.h
===================================================================
--- code/branches/pickup2/src/orxonox/overlays/OrxonoxOverlay.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/overlays/OrxonoxOverlay.h	(revision 6412)
@@ -155,4 +155,9 @@
         static void rotateOverlay(const std::string& name, const Degree& angle);
 
+        void setBackgroundMaterial(const std::string& material);
+        const std::string& getBackgroundMaterial() const;
+
+        void setBackgroundAlpha(float alpha);
+
         virtual void changedVisibility();
 
@@ -169,15 +174,9 @@
         virtual void changedOwner() {}
 
-        inline void setOverlayGroup(OverlayGroup* group)
-        {
-            if (group != this->group_)
-            {
-                this->group_ = group;
-                this->changedOverlayGroup();
-            }
-        }
+        void setOverlayGroup(OverlayGroup* group);
         inline OverlayGroup* getOverlayGroup() const
             { return this->group_; }
-        virtual void changedOverlayGroup() {}
+        virtual void changedOverlayGroup()
+            { this->changedVisibility(); }
 
     protected:
@@ -186,7 +185,4 @@
         virtual void sizeChanged();
         virtual void positionChanged();
-
-        void setBackgroundMaterial(const std::string& material);
-        const std::string& getBackgroundMaterial() const;
 
         Ogre::Overlay* overlay_;                   //!< The overlay the entire class is about.
@@ -211,4 +207,5 @@
         BaseObject* owner_;
         OverlayGroup* group_;
+        Ogre::Pass* backgroundAlphaPass_;
   };
 
Index: code/branches/pickup2/src/orxonox/overlays/OverlayGroup.cc
===================================================================
--- code/branches/pickup2/src/orxonox/overlays/OverlayGroup.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/overlays/OverlayGroup.cc	(revision 6412)
@@ -60,6 +60,7 @@
     OverlayGroup::~OverlayGroup()
     {
-        for (std::set<OrxonoxOverlay*>::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+        for (std::set< SmartPtr<OrxonoxOverlay> >::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
             (*it)->destroy();
+        this->hudElements_.clear();
     }
 
@@ -83,5 +84,5 @@
     void OverlayGroup::setScale(const Vector2& scale)
     {
-        for (std::set<OrxonoxOverlay*>::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+        for (std::set< SmartPtr<OrxonoxOverlay> >::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
             (*it)->scale(scale / this->scale_);
         this->scale_ = scale;
@@ -91,5 +92,5 @@
     void OverlayGroup::setScroll(const Vector2& scroll)
     {
-        for (std::set<OrxonoxOverlay*>::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+        for (std::set< SmartPtr<OrxonoxOverlay> >::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
             (*it)->scroll(scroll - this->scroll_);
         this->scroll_ = scroll;
@@ -104,6 +105,6 @@
     void OverlayGroup::addElement(OrxonoxOverlay* element)
     {
-        hudElements_.insert(element);
-        element->setVisible(this->isVisible());
+        hudElements_.insert(SmartPtr<OrxonoxOverlay>(element));
+        element->setOverlayGroup( this );
         if (this->owner_)
             element->setOwner(this->owner_);
@@ -120,5 +121,5 @@
     bool OverlayGroup::removeElement(OrxonoxOverlay* element)
     {
-        if(this->hudElements_.erase(element) == 0)
+        if(this->hudElements_.erase(SmartPtr<OrxonoxOverlay>(element)) == 0)
             return false;
         return true;
@@ -130,8 +131,8 @@
         if (index < this->hudElements_.size())
         {
-            std::set<OrxonoxOverlay*>::const_iterator it = hudElements_.begin();
+            std::set< SmartPtr<OrxonoxOverlay> >::const_iterator it = hudElements_.begin();
             for (unsigned int i = 0; i != index; ++it, ++i)
                 ;
-            return (*it);
+            return it->get();
         }
         else
@@ -142,6 +143,8 @@
     void OverlayGroup::changedVisibility()
     {
-        for (std::set<OrxonoxOverlay*>::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
-            (*it)->setVisible(this->isVisible());
+        SUPER( OverlayGroup, changedVisibility );
+
+        for (std::set< SmartPtr<OrxonoxOverlay> >::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+            (*it)->changedVisibility(); //inform all Child Overlays that our visibility has changed
     }
 
@@ -150,5 +153,5 @@
         this->owner_ = owner;
 
-        for (std::set<OrxonoxOverlay*>::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+        for (std::set< SmartPtr<OrxonoxOverlay> >::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
             (*it)->setOwner(owner);
     }
Index: code/branches/pickup2/src/orxonox/overlays/OverlayGroup.h
===================================================================
--- code/branches/pickup2/src/orxonox/overlays/OverlayGroup.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/overlays/OverlayGroup.h	(revision 6412)
@@ -64,5 +64,5 @@
         static void scrollGroup(const std::string& name, const Vector2& scroll);
 
-        inline const std::set<OrxonoxOverlay*>& getOverlays() const
+        inline const std::set< SmartPtr<OrxonoxOverlay> >& getOverlays() const
             { return this->hudElements_; }
 
@@ -90,5 +90,5 @@
 
     private:
-        std::set<OrxonoxOverlay*> hudElements_;    //!< Contains all the OrxonoxOverlays of the this group.
+        std::set< SmartPtr<OrxonoxOverlay> > hudElements_;    //!< Contains all the OrxonoxOverlays of the this group.
         Vector2 scale_;                            //!< Current scale (independent of the elements).
         Vector2 scroll_;                           //!< Current scrolling offset.
Index: code/branches/pickup2/src/orxonox/pickup/DroppedItem.cc
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/DroppedItem.cc	(revision 6412)
+++ code/branches/pickup2/src/orxonox/pickup/DroppedItem.cc	(revision 6412)
@@ -0,0 +1,123 @@
+/*
+ *   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:
+ *      Daniel 'Huty' Haggenmueller
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DroppedItem.h"
+
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "BaseItem.h"
+#include "graphics/Billboard.h"
+#include "graphics/Model.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(DroppedItem);
+
+    DroppedItem::DroppedItem(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(DroppedItem);
+
+        this->triggerDistance_ = 20.0f;
+        this->timeToLive_ = 0;
+        this->item_ = 0;
+    }
+    DroppedItem::~DroppedItem()
+    {
+    }
+    void DroppedItem::tick(float dt)
+    {
+        if (this->item_)
+        {
+            for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
+            {
+                Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
+                if (distance.length() < this->triggerDistance_)
+                    this->trigger(*it);
+            }
+        }
+    }
+    void DroppedItem::trigger(Pawn* pawn)
+    {
+        if (this->item_->pickedUp(pawn))
+        {
+            COUT(3) << "DroppedItem '" << this->item_->getPickupIdentifier() << "' picked up." << std::endl;
+            this->destroy();
+        }
+    }
+    void DroppedItem::createTimer()
+    {
+        if (this->timeToLive_ > 0)
+        {
+            this->timer_.setTimer(this->timeToLive_, false, createExecutor(createFunctor(&DroppedItem::timerCallback, this)), false);
+        }
+    }
+    void DroppedItem::timerCallback()
+    {
+        if (this->item_)
+        {
+            COUT(3) << "Delete DroppedItem with '" << this->item_->getPickupIdentifier() << '\'' << std::endl;
+            this->item_->destroy();
+        }
+
+        this->destroy();
+    }
+
+    DroppedItem* DroppedItem::createDefaultDrop(BaseItem* item, const Vector3& position, const ColourValue& flareColour, float timeToLive)
+    {
+        DroppedItem* drop = new DroppedItem(item);
+        Model* model = new Model(item);
+        Billboard* billboard = new Billboard(item);
+
+        model->setMeshSource("sphere.mesh");
+        model->setScale(3.0f);
+
+        billboard->setMaterial("Examples/Flare");
+        billboard->setColour(flareColour);
+        billboard->setScale(0.5f);
+
+        drop->setPosition(position);
+        drop->attach(model);
+        drop->attach(billboard);
+
+        drop->setItem(item);
+
+        drop->setTimeToLive(timeToLive);
+        drop->createTimer();
+
+        COUT(3) << "Created DroppedItem for '" << item->getPickupIdentifier() << "' at (" << position.x << ',' << position.y << ',' << position.z << ")." << std::endl;
+
+        return drop;
+    }
+    DroppedItem* DroppedItem::createDefaultDrop(BaseItem* item, Pawn* pawn, const ColourValue& flareColour, float timeToLive)
+    {
+        Vector3 after = pawn->getPosition() + pawn->getOrientation() * Vector3(0.0f, 0.0f, 50.0f);
+        return DroppedItem::createDefaultDrop(item, after, flareColour, timeToLive);
+    }
+}
Index: code/branches/pickup2/src/orxonox/pickup/ModifierPickup.cc
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/ModifierPickup.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/pickup/ModifierPickup.cc	(revision 6412)
@@ -106,10 +106,10 @@
             for (it = this->additiveModifiers_.begin(); it != this->additiveModifiers_.end(); it++)
             {
-                pawn->getPickups().addAdditiveModifier((*it).first, (*it).second);
+                pawn->getPickups().addAdditiveModifier(it->first, it->second);
             }
 
             for (it = this->multiplicativeModifiers_.begin(); it != this->multiplicativeModifiers_.end(); it++)
             {
-                pawn->getPickups().addMultiplicativeModifier((*it).first, (*it).second);
+                pawn->getPickups().addMultiplicativeModifier(it->first, it->second);
             }
 
@@ -146,10 +146,10 @@
             for (it = this->additiveModifiers_.begin(); it != this->additiveModifiers_.end(); it++)
             {
-                pawn->getPickups().removeAdditiveModifier((*it).first, (*it).second);
+                pawn->getPickups().removeAdditiveModifier(it->first, it->second);
             }
 
             for (it = this->multiplicativeModifiers_.begin(); it != this->multiplicativeModifiers_.end(); it++)
             {
-                pawn->getPickups().removeMultiplicativeModifier((*it).first, (*it).second);
+                pawn->getPickups().removeMultiplicativeModifier(it->first, it->second);
             }
 
@@ -186,5 +186,5 @@
         std::map<ModifierType::Value, float>::const_iterator it = this->additiveModifiers_.find(type);
         if (it != this->additiveModifiers_.end())
-            return (*it).second;
+            return it->second;
         else
             return 0.0f;
@@ -203,5 +203,5 @@
         std::map<ModifierType::Value, float>::const_iterator it = this->multiplicativeModifiers_.find(type);
         if (it != this->multiplicativeModifiers_.end())
-            return (*it).second;
+            return it->second;
         else
             return 1.0f;
Index: code/branches/pickup2/src/orxonox/pickup/PickupCollection.cc
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/PickupCollection.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/pickup/PickupCollection.cc	(revision 6412)
@@ -102,6 +102,6 @@
         for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
         {
-            if((*it).second && (*it).second->getOwner())
-                (*it).second->dropped((*it).second->getOwner());
+            if(it->second && it->second->getOwner())
+                it->second->dropped(it->second->getOwner());
         }
         this->currentUsable_ = NULL;
@@ -126,5 +126,5 @@
             for (std::multimap<std::string, BaseItem*>::iterator it = bounds.first; it != bounds.second && it != this->items_.end(); it++)
             {
-                if ((*it).second == item)
+                if (it->second == item)
                 {
                     return true;
@@ -178,5 +178,5 @@
             for (std::multimap<std::string, BaseItem*>::iterator it = bounds.first; it != bounds.second && it != this->items_.end(); it++)
             {
-                if ((*it).second == item)
+                if (it->second == item)
                 {
                     this->items_.erase(it);
@@ -219,5 +219,5 @@
         for (std::multimap<ModifierType::Value, float>::iterator it = range.first; it != range.second && it != this->additiveModifiers_.end(); it++)
         {
-            v += (*it).second;
+            v += it->second;
         }
 
@@ -234,5 +234,5 @@
         for (std::multimap<ModifierType::Value, float>::iterator it = range.first; it != range.second && it != this->additiveModifiers_.end(); it++)
         {
-            if ((*it).second == value)
+            if (it->second == value)
             {
                 this->additiveModifiers_.erase(it);
@@ -262,5 +262,5 @@
         for (std::multimap<ModifierType::Value, float>::iterator it = range.first; it != range.second && it != this->multiplicativeModifiers_.end(); it++)
         {
-            v *= (*it).second;
+            v *= it->second;
         }
 
@@ -277,5 +277,5 @@
         for (std::multimap<ModifierType::Value, float>::iterator it = range.first; it != range.second && it != this->multiplicativeModifiers_.end(); it++)
         {
-            if ((*it).second == value)
+            if (it->second == value)
             {
                 this->multiplicativeModifiers_.erase(it);
@@ -337,6 +337,6 @@
         for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
         {
-            if ((*it).second->isA(ident))
-                ret.push_back(orxonox_cast<EquipmentItem*>((*it).second));
+            if (it->second->isA(ident))
+                ret.push_back(orxonox_cast<EquipmentItem*>(it->second));
         }
 
@@ -354,6 +354,6 @@
         for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
         {
-            if ((*it).second->isA(ident))
-                ret.push_back(orxonox_cast<PassiveItem*>((*it).second));
+            if (it->second->isA(ident))
+                ret.push_back(orxonox_cast<PassiveItem*>(it->second));
         }
 
@@ -371,6 +371,6 @@
         for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
         {
-            if ((*it).second->isA(ident))
-                ret.push_back(orxonox_cast<UsableItem*>((*it).second));
+            if (it->second->isA(ident))
+                ret.push_back(orxonox_cast<UsableItem*>(it->second));
         }
 
Index: code/branches/pickup2/src/orxonox/pickup/PickupInventory.cc
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/PickupInventory.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/pickup/PickupInventory.cc	(revision 6412)
@@ -110,13 +110,9 @@
     {
         if(PickupInventory::getSingleton()->isVisible()) {
-            GUIManager::getInstance().executeCode("hideGUI(\"PickupInventory\")");
-            GUIManager::getInstance().executeCode("hideCursor()");
-            InputManager::getInstance().leaveState("guiMouseOnly");
-        }
-        else
-        {
-            GUIManager::getInstance().showGUI("PickupInventory");
-            GUIManager::getInstance().executeCode("showCursor()");
-            InputManager::getInstance().enterState("guiMouseOnly");
+            GUIManager::hideGUI("PickupInventory");
+        }
+        else
+        {
+            GUIManager::showGUI("PickupInventory");
         }
         PickupInventory::getSingleton()->setVisible(!PickupInventory::getSingleton()->isVisible());
@@ -235,5 +231,5 @@
             return "";
 
-        std::string name = "pickup_" + item->getGUIImage();
+        const std::string& name = "pickup_" + item->getGUIImage();
 
         if(!CEGUI::ImagesetManager::getSingletonPtr()->isImagesetPresent(name))
@@ -242,5 +238,5 @@
         }
 
-        return "set:" + name + " image:full_image";
+        return ("set:" + name + " image:full_image");
     }
 
@@ -374,7 +370,7 @@
         txt->setVisible(true);
         txt->setProperty("Text", item->getGUIText());
-        txt->setProperty("TextColours", "tl:" + textColour + " tr:" + textColour + " bl:" + textColour + " br:" + textColour + "");
-
-        std::string image = PickupInventory::getImageForItem(item);
+        txt->setProperty("TextColours", "tl:" + textColour + " tr:" + textColour + " bl:" + textColour + " br:" + textColour);
+
+        const std::string& image = PickupInventory::getImageForItem(item);
         btn->setVisible(true);
         btn->setProperty("NormalImage", image);
Index: code/branches/pickup2/src/orxonox/pickup/PickupSpawner.cc
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/PickupSpawner.cc	(revision 6412)
+++ code/branches/pickup2/src/orxonox/pickup/PickupSpawner.cc	(revision 6412)
@@ -0,0 +1,270 @@
+/*
+ *   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:
+ *      Daniel 'Huty' Haggenmueller
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of PickupSpawner.
+*/
+
+#include "PickupSpawner.h"
+
+#include "BaseItem.h"
+
+#include "core/CoreIncludes.h"
+#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
+
+
+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);
+
+    /**
+    @brief
+        Constructor. Registers the PickupSpawner.
+    @param creator
+        Pointer to the object which created this item.
+    */
+    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_ = NULL;
+        this->triggerDistance_ = 20;
+        this->respawnTime_ = 0.0f;
+        this->tickSum_ = 0.0f;
+        this->maxSpawnedItems_ = INF;
+        this->spawnsRemaining_ = INF;
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    PickupSpawner::~PickupSpawner()
+    {
+        
+    }
+
+    /**
+    @brief
+        Method for creating a PickupSpawner through XML.
+    @param xmlelement
+        XML element which contains the PickupSpawner.
+    @param mode
+        XMLPort mode.
+    */
+    void PickupSpawner::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(PickupSpawner, XMLPort, xmlelement, mode);
+
+        XMLPortParam(PickupSpawner, "item", setItemTemplateName, getItemTemplateName, xmlelement, mode);
+        XMLPortParam(PickupSpawner, "triggerDistance", setTriggerDistance, getTriggerDistance, xmlelement, mode);
+        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::showGUI("PickupInventory");
+        GUIManager::hideGUI("PickupInventory");
+        PickupInventory::getSingleton();
+    }
+
+    /**
+    @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
+        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::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.
+    void PickupSpawner::tick(float dt)
+    {
+        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)
+            {
+                Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
+                if (distance.length() < this->triggerDistance_)
+                    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.
+
+    @param pawn
+        Pawn which triggered the PickupSpawner.
+    */
+    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.
+            {
+                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();
+                    }
+                }
+                else
+                {
+                    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);
+    }
+
+    /**
+    @brief
+        Invoked by the timer, re-activates the PickupSpawner.
+    */
+    void PickupSpawner::respawnTimerCallback()
+    {
+        COUT(3) << "PickupSpawner reactivated." << std::endl;
+
+        this->setActive(true);
+    }
+}
Index: code/branches/pickup2/src/orxonox/pickup/UsableItem.cc
===================================================================
--- code/branches/pickup2/src/orxonox/pickup/UsableItem.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/pickup/UsableItem.cc	(revision 6412)
@@ -26,5 +26,5 @@
  *
  */
-        
+
 /**
     @file
@@ -41,5 +41,5 @@
     @param creator Pointer to the object which created this item.
     */
-    UsableItem::UsableItem(BaseObject* creator) : BaseItem(creator) 
+    UsableItem::UsableItem(BaseObject* creator) : BaseItem(creator)
     {
         RegisterObject(UsableItem);
Index: code/branches/pickup2/src/orxonox/sound/AmbientSound.cc
===================================================================
--- code/branches/pickup2/src/orxonox/sound/AmbientSound.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/sound/AmbientSound.cc	(revision 6412)
@@ -31,5 +31,8 @@
 #include "core/CoreIncludes.h"
 #include "core/EventIncludes.h"
+#include "core/GameMode.h"
+#include "core/Resource.h"
 #include "core/XMLPort.h"
+#include "SoundManager.h"
 
 namespace orxonox
@@ -39,10 +42,29 @@
     AmbientSound::AmbientSound(BaseObject* creator)
         : BaseObject(creator)
+        , Synchronisable(creator)
+        , bPlayOnLoad_(false)
     {
         RegisterObject(AmbientSound);
+
+        // Ambient sounds always fade in
+        this->setVolume(0);
+        this->registerVariables();
     }
 
-    AmbientSound::~AmbientSound()
+    void AmbientSound::preDestroy()
     {
+        if (GameMode::playsSound())
+        {
+            // Smoothly fade out by keeping a SmartPtr
+            SoundManager::getInstance().unregisterAmbientSound(this);
+        }
+    }
+
+    void AmbientSound::registerVariables()
+    {
+        registerVariable(ambientSource_, ObjectDirection::ToClient, new NetworkCallback<AmbientSound>(this, &AmbientSound::ambientSourceChanged));
+        registerVariable(bLooping_,      ObjectDirection::ToClient, new NetworkCallback<AmbientSound>(this, &AmbientSound::loopingChanged));
+        registerVariable(pitch_,         ObjectDirection::ToClient, new NetworkCallback<AmbientSound>(this, &AmbientSound::pitchChanged));
+        registerVariable(bPlayOnLoad_,   ObjectDirection::ToClient, new NetworkCallback<AmbientSound>(this, &AmbientSound::playOnLoadChanged));
     }
 
@@ -50,7 +72,7 @@
     {
         SUPER(AmbientSound, XMLPort, xmlelement, mode);
-        XMLPortParamExtern(AmbientSound, BaseSound, this, "source", setSource, getSource, xmlelement, mode);
-        XMLPortParamExtern(AmbientSound, BaseSound, this, "loop", setLoop, getLoop, xmlelement, mode);
-        XMLPortParamExtern(AmbientSound, BaseSound, this, "playOnLoad", setPlayOnLoad, getPlayOnLoad, xmlelement, mode);
+        BaseSound::XMLPortExtern(xmlelement, mode);
+        XMLPortParam(AmbientSound, "ambientSource", setAmbientSource, getAmbientSource, xmlelement, mode);
+        XMLPortParam(AmbientSound, "playOnLoad", setPlayOnLoad, getPlayOnLoad, xmlelement, mode);
     }
 
@@ -60,3 +82,62 @@
         XMLPortEventState(AmbientSound, BaseObject, "play", play, xmlelement, mode);
     }
+
+    void AmbientSound::play()
+    {
+        if (GameMode::playsSound())
+            SoundManager::getInstance().registerAmbientSound(this);
+    }
+
+    void AmbientSound::stop()
+    {
+        if (GameMode::playsSound())
+            SoundManager::getInstance().unregisterAmbientSound(this);
+    }
+
+    void AmbientSound::pause()
+    {
+        if (GameMode::playsSound())
+            SoundManager::getInstance().pauseAmbientSound(this);
+    }
+
+    float AmbientSound::getRealVolume()
+    {
+        assert(GameMode::playsSound());
+        return SoundManager::getInstance().getRealVolume(SoundType::Music);
+    }
+
+    void AmbientSound::setAmbientSource(const std::string& source)
+    {
+        this->ambientSource_ = source;
+        this->moodChanged(this->getMood());
+    }
+
+    void AmbientSound::moodChanged(const std::string& mood)
+    {
+        if (GameMode::playsSound())
+        {
+            const std::string& path = "ambient/" + MoodManager::getInstance().getMood() + '/' + this->ambientSource_;
+            shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(path);
+            if (fileInfo != NULL)
+                this->setSource(path);
+            else
+                COUT(3) << "Sound: " << this->ambientSource_ << ": Not a valid name! Ambient sound will not change." << std::endl;
+        }
+    }
+
+    void AmbientSound::setPlayOnLoad(bool val)
+    {
+        this->bPlayOnLoad_ = val;
+        if (val)
+            this->play();
+    }
+
+    void AmbientSound::changedActivity()
+    {
+        SUPER(AmbientSound, changedActivity);
+        if (this->isActive())
+            this->play();
+        else
+            this->stop();
+    }
 }
Index: code/branches/pickup2/src/orxonox/sound/AmbientSound.h
===================================================================
--- code/branches/pickup2/src/orxonox/sound/AmbientSound.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/sound/AmbientSound.h	(revision 6412)
@@ -22,8 +22,10 @@
  *   Author:
  *      Reto Grieder
+ *      Kevin Young
  *   Co-authors:
  *      ...
  *
  */
+
 #ifndef _AmbientSound_H__
 #define _AmbientSound_H__
@@ -32,5 +34,7 @@
 
 #include "core/BaseObject.h"
-#include "sound/BaseSound.h"
+#include "network/synchronisable/Synchronisable.h"
+#include "BaseSound.h"
+#include "MoodManager.h"
 
 namespace orxonox
@@ -41,14 +45,42 @@
      *
      */
-    class _OrxonoxExport AmbientSound : public BaseSound, public BaseObject
+    class _OrxonoxExport AmbientSound : public BaseSound, public BaseObject, public Synchronisable, public MoodListener
     {
+        friend class SoundManager;
+
     public:
         AmbientSound(BaseObject* creator);
-        virtual ~AmbientSound();
 
-        virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-        virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+        void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+        void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+        void changedActivity();
+
+        void play();
+        void stop();
+        void pause();
+
+        void setAmbientSource(const std::string& source);
+        inline const std::string& getAmbientSource() const
+            { return this->ambientSource_; }
+
+        void setPlayOnLoad(bool val);
+        bool getPlayOnLoad() const
+            { return this->bPlayOnLoad_; }
+
+    protected:
+        ~AmbientSound() { }
 
     private:
+        void preDestroy();
+        void registerVariables();
+        float getRealVolume();
+        void moodChanged(const std::string& mood);
+        inline void ambientSourceChanged()
+            { this->setAmbientSource(this->ambientSource_); }
+        inline void playOnLoadChanged()
+            { this->setPlayOnLoad(this->bPlayOnLoad_); }
+
+        std::string ambientSource_; //!< Analogous to source_, but mood independent
+        bool        bPlayOnLoad_;   //!< Play the sound immediately when loaded
     };
 }
Index: code/branches/pickup2/src/orxonox/sound/BaseSound.cc
===================================================================
--- code/branches/pickup2/src/orxonox/sound/BaseSound.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/sound/BaseSound.cc	(revision 6412)
@@ -29,234 +29,249 @@
 #include "BaseSound.h"
 
+#include <cassert>
 #include <vector>
-#include <AL/alut.h>
-#include <vorbis/vorbisfile.h>
+#include <al.h>
 
 #include "core/CoreIncludes.h"
 #include "core/GameMode.h"
 #include "core/Resource.h"
+#include "core/XMLPort.h"
+#include "SoundBuffer.h"
+#include "SoundManager.h"
 
 namespace orxonox
 {
     BaseSound::BaseSound()
-        : audioSource_(0)
-        , audioBuffer_(0)
-        , bPlayOnLoad_(false)
-        , bLoop_(false)
+        : bPooling_(false)
+        , volume_(1.0)
+        , bLooping_(false)
+        , state_(Stopped)
+        , pitch_ (1.0)
     {
         RegisterRootObject(BaseSound);
+
+        // Initialise audioSource_ to a value that is not a source
+        // 0 is unfortunately not guaranteed to be no source ID.
+        this->audioSource_ = 123456789;
+        while (alIsSource(++this->audioSource_));
     }
 
     BaseSound::~BaseSound()
     {
-        this->setSource("");
-    }
-
-    void BaseSound::play()
-    {
-        if (alIsSource(this->audioSource_))
-        {
-            if (this->bLoop_)
-                alSourcei(this->audioSource_, AL_LOOPING, AL_TRUE);
-            else
-                alSourcei(this->audioSource_, AL_LOOPING, AL_FALSE);
+        this->stop();
+        // Release buffer
+        if (this->soundBuffer_ != NULL)
+        {
+            assert(GameMode::playsSound());
+            SoundManager::getInstance().releaseSoundBuffer(this->soundBuffer_, this->bPooling_);
+        }
+    }
+
+    void BaseSound::XMLPortExtern(Element& xmlelement, XMLPort::Mode mode)
+    {
+        XMLPortParam(BaseSound, "volume",  setVolume,  getVolume,  xmlelement, mode);
+        XMLPortParam(BaseSound, "looping", setLooping, getLooping, xmlelement, mode);
+        XMLPortParam(BaseSound, "pitch",   setPitch,   getPitch,   xmlelement, mode);
+        XMLPortParam(BaseSound, "source",  setSource,  getSource,  xmlelement, mode);
+    }
+
+    void BaseSound::doPlay()
+    {
+        this->state_ = Playing;
+        if (GameMode::playsSound() && this->getSourceState() != AL_PLAYING && this->soundBuffer_ != NULL)
+        {
+            if (!alIsSource(this->audioSource_))
+            {
+                this->audioSource_ = SoundManager::getInstance().getSoundSource(this);
+                if (!alIsSource(this->audioSource_))
+                    return;
+                this->initialiseSource();
+            }
+
             alSourcePlay(this->audioSource_);
-
-            if (alGetError() != AL_NO_ERROR)
-            {
-                 COUT(2) << "Sound: OpenAL: Error playin sound " << this->audioSource_ << std::endl;
-            }
-        }
-    }
-
-    void BaseSound::stop()
-    {
-        if (alIsSource(this->audioSource_))
+            if (int error = alGetError())
+                COUT(2) << "Sound: Error playing sound: " << SoundManager::getALErrorString(error) << std::endl;
+        }
+    }
+
+    void BaseSound::doStop()
+    {
+        this->state_ = Stopped;
+        if (alIsSource(this->audioSource_))
+        {
             alSourceStop(this->audioSource_);
-    }
-
-    void BaseSound::pause()
-    {
+            // Release buffer
+            alSourcei(this->audioSource_, AL_BUFFER, AL_NONE);
+            // Release source again
+            SoundManager::getInstance().releaseSoundSource(this->audioSource_);
+            // Get a no source ID
+            this->audioSource_ += 123455;
+            while (alIsSource(++this->audioSource_));
+        }
+    }
+
+    void BaseSound::doPause()
+    {
+        if (this->isStopped())
+            return;
+        this->state_ = Paused;
         if (alIsSource(this->audioSource_))
             alSourcePause(this->audioSource_);
     }
 
-    bool BaseSound::isPlaying()
-    {
-        if (alIsSource(this->audioSource_))
-            return getSourceState() == AL_PLAYING;
-        return false;
-    }
-
-    bool BaseSound::isPaused()
-    {
-        if (alIsSource(this->audioSource_))
-            return getSourceState() == AL_PAUSED;
-        return true;
-    }
-
-    bool BaseSound::isStopped()
-    {
-        if (alIsSource(this->audioSource_))
-            return getSourceState() == AL_INITIAL || getSourceState() == AL_STOPPED;
-        return true;
-    }
-
-    void BaseSound::setPlayOnLoad(bool val)
-    {
-        this->bPlayOnLoad_ = true;
-        this->play();
+    ALint BaseSound::getSourceState() const
+    {
+        if (alIsSource(this->audioSource_))
+        {
+            ALint state;
+            alGetSourcei(this->audioSource_, AL_SOURCE_STATE, &state);
+            return state;
+        }
+        else
+            return AL_INITIAL;
+    }
+
+    void BaseSound::initialiseSource()
+    {
+        this->updateVolume();
+        this->setPitch(this->getPitch());
+        this->setLooping(this->getLooping());
+        alSource3f(this->audioSource_, AL_POSITION,  0, 0, 0);
+        alSource3f(this->audioSource_, AL_VELOCITY,  0, 0, 0);
+        alSource3f(this->audioSource_, AL_DIRECTION, 0, 0, 0);
+        if (ALint error = alGetError())
+            COUT(2) << "Sound Warning: Setting source parameters to 0 failed: "
+                    << SoundManager::getALErrorString(error) << std::endl;
+        assert(this->soundBuffer_ != NULL);
+        alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
+        if (ALuint error = alGetError())
+            COUT(1) << "Sound Error: Could not set buffer \"" << this->source_ << "\": " << SoundManager::getALErrorString(error) << std::endl;
+    }
+
+    void BaseSound::setVolume(float vol)
+    {
+        this->volume_ = clamp(vol, 0.0f, 1.0f);
+        if (this->volume_ != vol)
+            COUT(2) << "Sound warning: volume out of range, clamping value." << std::endl;
+        this->updateVolume();
+    }
+
+    void BaseSound::updateVolume()
+    {
+        if (alIsSource(this->audioSource_))
+        {
+            float volume = this->volume_ * this->getRealVolume();
+            alSourcef(this->audioSource_, AL_GAIN, volume);
+            if (int error = alGetError())
+                COUT(2) << "Sound: Error setting volume to " << volume
+                        << ": " << SoundManager::getALErrorString(error) << std::endl;
+        }
+    }
+
+    void BaseSound::setLooping(bool val)
+    {
+        this->bLooping_ = val;
+        if (alIsSource(this->audioSource_))
+            alSourcei(this->audioSource_, AL_LOOPING, (val ? AL_TRUE : AL_FALSE));
+    }
+
+    void BaseSound::setPitch(float pitch)
+    {
+        if (pitch > 2 || pitch < 0.5)
+        {
+            COUT(2) << "Sound warning: pitch out of range, cropping value." << std::endl;
+            pitch = pitch > 2 ? 2 : pitch;
+            pitch = pitch < 0.5 ? 0.5 : pitch;
+        }
+        this->pitch_ = pitch;
+        if (alIsSource(this->audioSource_))
+        {
+            alSourcef(this->audioSource_, AL_PITCH, pitch);
+            if (int error = alGetError())
+                COUT(2) << "Sound: Error setting pitch: " << SoundManager::getALErrorString(error) << std::endl;
+        }
     }
 
     void BaseSound::setSource(const std::string& source)
     {
+        if (!GameMode::playsSound())
+        {
+            this->source_ = source;
+            return;
+        }
+
+        if (this->soundBuffer_ != NULL)
+        {
+            if (this->soundBuffer_->getFilename() == source)
+            {
+                assert(this->source_ == source_);
+                return;
+            }
+            // Stopping is imperative here!
+            if (alIsSource(this->audioSource_))
+            {
+                alSourceStop(this->audioSource_);
+                alSourcei(this->audioSource_, AL_BUFFER, AL_NONE);
+            }
+            SoundManager::getInstance().releaseSoundBuffer(this->soundBuffer_, this->bPooling_);
+            this->soundBuffer_.reset();
+        }
+
         this->source_ = source;
-        if (!GameMode::playsSound())
-            return;
-
-        if (source.empty() && alIsSource(this->audioSource_))
-        {
-            // Unload sound
-            alSourcei(this->audioSource_, AL_BUFFER, 0);
-            alDeleteSources(1, &this->audioSource_);
-            alDeleteBuffers(1, &this->audioBuffer_);
-            return;
-        }
-
-        COUT(3) << "Sound: OpenAL ALUT: loading file " << source << std::endl;
-        // Get DataStream from the resources
-        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(source);
-        if (fileInfo == NULL)
-        {
-            COUT(2) << "Warning: Sound file '" << source << "' not found" << std::endl;
-            return;
-        }
-        dataStream_ = Resource::open(source);
-        // Read everything into a temporary buffer
-        char* buffer = new char[fileInfo->size];
-        dataStream_->read(buffer, fileInfo->size);
-        dataStream_->seek(0);
-
-        this->audioBuffer_ = alutCreateBufferFromFileImage(buffer, fileInfo->size);
-        delete[] buffer;
-
-        if (this->audioBuffer_ == AL_NONE)
-        {
-            COUT(2) << "Sound: OpenAL ALUT: " << alutGetErrorString(alutGetError()) << std::endl;
-            if (source.find("ogg", 0) != std::string::npos)
-            {
-                COUT(2) << "Sound: Trying fallback ogg loader" << std::endl;
-                this->audioBuffer_ = loadOggFile();
-            }
-
-            if (this->audioBuffer_ == AL_NONE)
-            {
-                COUT(2) << "Sound: fallback ogg loader failed: " << alutGetErrorString(alutGetError()) << std::endl;
+        // Don't load ""
+        if (source_.empty())
+            return;
+
+        // Get new sound buffer
+        this->soundBuffer_ = SoundManager::getInstance().getSoundBuffer(this->source_);
+        if (this->soundBuffer_ == NULL)
+            return;
+
+        if (alIsSource(this->audioSource_)) // already playing or paused
+        {
+            // Set new buffer
+            alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
+            if (ALuint error = alGetError())
+            {
+                COUT(1) << "Sound Error: Could not set buffer \"" << source << "\": " << SoundManager::getALErrorString(error) << std::endl;
                 return;
             }
-        }
-
-        alGenSources(1, &this->audioSource_);
-        alSourcei(this->audioSource_, AL_BUFFER, this->audioBuffer_);
-        if (alGetError() != AL_NO_ERROR)
-        {
-            COUT(2) << "Sound: OpenAL: Error loading sample file: " << source << std::endl;
-            return;
-        }
-
-        alSource3f(this->audioSource_, AL_POSITION,  0, 0, 0);
-
-        if (this->bPlayOnLoad_)
-            this->play();
-    }
-
-    ALint BaseSound::getSourceState()
-    {
-        ALint state;
-        alGetSourcei(this->audioSource_, AL_SOURCE_STATE, &state);
-        return state;
-    }
-
-    size_t readVorbis(void* ptr, size_t size, size_t nmemb, void* datasource)
-    {
-        return static_cast<Ogre::DataStream*>(datasource)->read(ptr, size * nmemb);
-    }
-
-    int seekVorbis(void* datasource, ogg_int64_t offset, int whence)
-    {
-        Ogre::DataStream* stream = static_cast<Ogre::DataStream*>(datasource);
-        int offset_beg = offset;
-        if (whence == SEEK_CUR)
-            offset_beg = stream->tell() + offset;
-        else if (whence == SEEK_END)
-            offset_beg = stream->size() + offset;
-        else if (whence != SEEK_SET)
-            return -1;
-        stream->seek(offset_beg);
-        return 0;
-    }
-
-    long tellVorbis(void* datasource)
-    {
-        return static_cast<long>(static_cast<Ogre::DataStream*>(datasource)->tell());
-    }
-
-    ALuint BaseSound::loadOggFile()
-    {
-        char inbuffer[4096];
-        std::vector<char> outbuffer;
-        OggVorbis_File vf;
-        vorbis_info* vorbisInfo;
-        int eof = false;
-        int current_section;
-        ALuint buffer;
-        ALenum format;
-
-        // Open file with custom streaming
-        ov_callbacks vorbisCallbacks;
-        vorbisCallbacks.read_func  = &readVorbis;
-        vorbisCallbacks.seek_func  = &seekVorbis;
-        vorbisCallbacks.tell_func  = &tellVorbis;
-        vorbisCallbacks.close_func = NULL;
-
-        int ret = ov_open_callbacks(dataStream_.get(), &vf, NULL, 0, vorbisCallbacks);
-        if (ret < 0)
-        {
-            COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
-            ov_clear(&vf);
-            return AL_NONE;
-        }
-
-        while (!eof)
-        {
-            long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
-            if (ret == 0)
-            {
-                eof = true;
-            }
-            else if (ret < 0)
-            {
-                COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
-                ov_clear(&vf);
-                return AL_NONE;
-            }
-            else
-            {
-                outbuffer.insert(outbuffer.end(), inbuffer, inbuffer + sizeof(inbuffer));
-            }
-        }
-
-        vorbisInfo = ov_info(&vf, -1);
-        if (vorbisInfo->channels == 1)
-            format = AL_FORMAT_MONO16;
-        else
-            format = AL_FORMAT_STEREO16;
-
-        alGenBuffers(1, &buffer);
-        alBufferData(buffer, format, &outbuffer[0], outbuffer.size(), vorbisInfo->rate);
-        ov_clear(&vf);
-
-        return buffer;
-    }
-
-} // namespace: orxonox
+
+            // Sound was already playing or paused because there was a source acquired
+            assert(this->isPlaying() || this->isPaused());
+            alSourcePlay(this->audioSource_);
+            if (int error = alGetError())
+                COUT(2) << "Sound: Error playing sound: " << SoundManager::getALErrorString(error) << std::endl;
+            if (this->isPaused())
+                alSourcePause(this->audioSource_);
+        }
+        else // No source acquired so far, but might be set to playing or paused
+        {
+            State state = this->state_; // save
+            if (this->isPlaying() || this->isPaused())
+                doPlay();
+            if (state == Paused)
+            {
+                this->state_ = Paused;
+                doPause();
+            }
+        }
+    }
+
+    void BaseSound::stateChanged()
+    {
+        switch (this->state_)
+        {
+            case Playing:
+                this->play();
+                break;
+            case Paused:
+                this->pause();
+                break;
+            case Stopped:
+            default:
+                this->stop();
+                break;
+        }
+    }
+}
Index: code/branches/pickup2/src/orxonox/sound/BaseSound.h
===================================================================
--- code/branches/pickup2/src/orxonox/sound/BaseSound.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/sound/BaseSound.h	(revision 6412)
@@ -26,4 +26,5 @@
  *
  */
+
 #ifndef _BaseSound_H__
 #define _BaseSound_H__
@@ -32,5 +33,5 @@
 
 #include <string>
-#include <OgreSharedPtr.h>
+#include <boost/shared_ptr.hpp>
 #include <OgreDataStream.h>
 #include "core/OrxonoxClass.h"
@@ -47,35 +48,73 @@
     public:
         BaseSound();
+
+        void XMLPortExtern(Element& xmlelement, XMLPort::Mode mode);
+
+        virtual void play()  { this->doPlay(); }
+        virtual void stop()  { this->doStop(); }
+        virtual void pause() { this->doPause(); }
+
+        bool isPlaying() const { return this->state_ == Playing; }
+        bool isPaused()  const { return this->state_ == Paused; }
+        bool isStopped() const { return this->state_ == Stopped; }
+
+        virtual void setSource(const std::string& source);
+        virtual const std::string& getSource() const
+            { return this->source_; }
+
+        void setVolume(float vol);
+        float getVolume() const
+            { return this->volume_; }
+        void updateVolume();
+
+        bool getLooping() const
+            { return this->bLooping_; }
+        void setLooping(bool val);
+
+        float getPitch() const
+            { return this->pitch_; }
+        void setPitch(float pitch);
+
+    protected:
+        enum State
+        {
+            Stopped,
+            Playing,
+            Paused
+        };
+
         virtual ~BaseSound();
 
-        void play();
-        void stop();
-        void pause();
+        void doPlay();
+        void doStop();
+        void doPause();
 
-        bool isPlaying();
-        bool isPaused();
-        bool isStopped();
+        // network callbacks
+        inline void pitchChanged()
+            { this->setPitch(this->pitch_); }
+        inline void loopingChanged()
+            { this->setLooping(this->bLooping_); }
+        inline void volumeChanged()
+            { this->setVolume(this->volume_); }
+        inline void sourceChanged()
+            { this->setSource(this->source_); }
+        void stateChanged();
 
-        void setSource(const std::string& source);
-        const std::string& getSource() { return this->source_; }
+        virtual void initialiseSource();
+        ALint getSourceState() const;
 
-        bool getPlayOnLoad() { return this->bPlayOnLoad_; }
-        void setPlayOnLoad(bool val);
+        virtual float getRealVolume() = 0;
 
-        bool getLoop() { return this->bLoop_; }
-        void setLoop(bool val) { this->bLoop_ = val; }
-
-    protected:
-        ALuint loadOggFile();
-        ALint getSourceState();
-
-        ALuint audioSource_;
-        ALuint audioBuffer_;
+        ALuint          audioSource_;
+        bool            bPooling_;
+        shared_ptr<SoundBuffer> soundBuffer_;
+        std::string     source_;
+        float           volume_;
+        bool            bLooping_;
+        State           state_;
+        float           pitch_;
 
     private:
-        std::string source_;
-        bool bPlayOnLoad_;
-        bool bLoop_;
-        DataStreamPtr dataStream_;
+        DataStreamPtr   dataStream_;
     };
 }
Index: code/branches/pickup2/src/orxonox/sound/CMakeLists.txt
===================================================================
--- code/branches/pickup2/src/orxonox/sound/CMakeLists.txt	(revision 6405)
+++ code/branches/pickup2/src/orxonox/sound/CMakeLists.txt	(revision 6412)
@@ -2,6 +2,8 @@
     AmbientSound.cc
     BaseSound.cc
+    SoundBuffer.cc
     SoundManager.cc
     WorldSound.cc
+    SoundStreamer.cc
 )
 
Index: code/branches/pickup2/src/orxonox/sound/SoundBuffer.cc
===================================================================
--- code/branches/pickup2/src/orxonox/sound/SoundBuffer.cc	(revision 6412)
+++ code/branches/pickup2/src/orxonox/sound/SoundBuffer.cc	(revision 6412)
@@ -0,0 +1,187 @@
+/*
+ *   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:
+ *      Reto Grieder
+ *      Erwin 'vaiursch' Herrsche
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SoundBuffer.h"
+
+#include <AL/alut.h>
+#include <vorbis/vorbisfile.h>
+
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "sound/SoundManager.h"
+
+namespace orxonox
+{
+    SoundBuffer::SoundBuffer(const std::string& filename, std::list<shared_ptr<SoundBuffer> >::iterator poolIterator)
+        : filename_(filename)
+        , audioBuffer_(AL_NONE)
+        , poolIterator_(poolIterator)
+    {
+        if (this->filename_.empty())
+            ThrowException(General, "SoundBuffer construction: fileInfo was NULL");
+
+        // Get resource info
+        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(filename);
+        if (fileInfo == NULL)
+        {
+            COUT(2) << "Sound: Warning: Sound file '" << filename << "' not found" << std::endl;
+            return;
+        }
+        // Open data stream
+        DataStreamPtr dataStream = Resource::open(fileInfo);
+
+        const std::string& extension = this->filename_.substr(this->filename_.find_last_of('.') + 1);
+        if (getLowercase(extension) == "ogg")
+        {
+            // Try ogg loader
+            this->loadOgg(fileInfo, dataStream);
+        }
+        else
+        {
+            // Try standard OpenAL loader
+            this->loadStandard(fileInfo, dataStream);
+        }
+    }
+
+    SoundBuffer::~SoundBuffer()
+    {
+        // Destroy buffer
+        alDeleteBuffers(1, &this->audioBuffer_);
+    }
+
+    unsigned int SoundBuffer::getSize() const
+    {
+        ALint size;
+        alGetBufferi(this->audioBuffer_, AL_SIZE, &size);
+        return alGetError() ? 0 : size;
+    }
+
+    void SoundBuffer::loadStandard(const shared_ptr<ResourceInfo>& fileInfo, DataStreamPtr dataStream)
+    {
+        // Read everything into a temporary buffer
+        char* buffer = new char[fileInfo->size];
+        dataStream->read(buffer, fileInfo->size);
+        dataStream->seek(0);
+
+        this->audioBuffer_ = alutCreateBufferFromFileImage(buffer, fileInfo->size);
+        delete[] buffer;
+
+        if (!alIsBuffer(this->audioBuffer_))
+            ThrowException(General, "Sound Error: Standard file loader failed: " << alutGetErrorString(alutGetError()));
+    }
+
+    size_t readVorbis(void* ptr, size_t size, size_t nmemb, void* datasource)
+    {
+        return static_cast<Ogre::DataStream*>(datasource)->read(ptr, size * nmemb);
+    }
+
+    int seekVorbis(void* datasource, ogg_int64_t offset, int whence)
+    {
+        Ogre::DataStream* stream = static_cast<Ogre::DataStream*>(datasource);
+        switch (whence)
+        {
+        case SEEK_SET:
+            stream->seek(offset);
+            break;
+        case SEEK_CUR:
+            stream->skip(offset);
+            break;
+        case SEEK_END:
+            stream->seek(stream->size() + offset);
+            break;
+        default:
+            return -1;
+        }
+        return 0;
+    }
+
+    long tellVorbis(void* datasource)
+    {
+        return static_cast<long>(static_cast<Ogre::DataStream*>(datasource)->tell());
+    }
+
+    void SoundBuffer::loadOgg(const shared_ptr<ResourceInfo>& fileInfo, DataStreamPtr dataStream)
+    {
+        char inbuffer[256*1024];
+        std::vector<char> outbuffer;
+        outbuffer.reserve(80*1024*1024);
+
+        // Open file with custom streaming
+        ov_callbacks vorbisCallbacks;
+        vorbisCallbacks.read_func  = &readVorbis;
+        vorbisCallbacks.seek_func  = &seekVorbis;
+        vorbisCallbacks.tell_func  = &tellVorbis;
+        vorbisCallbacks.close_func = NULL;
+
+        OggVorbis_File vf;
+        int ret = ov_open_callbacks(dataStream.get(), &vf, NULL, 0, vorbisCallbacks);
+        if (ret < 0)
+        {
+            COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
+            ov_clear(&vf);
+            ThrowException(General, "Sound Error: Ogg file loader failed when opening the bitstream");
+        }
+
+        int current_section;
+        int eof = false;
+        while (!eof)
+        {
+            long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
+            if (ret == 0)
+            {
+                eof = true;
+            }
+            else if (ret < 0)
+            {
+                COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
+                ov_clear(&vf);
+                ThrowException(General, "Sound Error: Ogg file loader failed when decoding the file");
+            }
+            else
+            {
+                outbuffer.insert(outbuffer.end(), inbuffer, inbuffer + ret);
+            }
+        }
+
+        vorbis_info* vorbisInfo;
+        vorbisInfo = ov_info(&vf, -1);
+        ALenum format;
+        if (vorbisInfo->channels == 1)
+            format = AL_FORMAT_MONO16;
+        else
+            format = AL_FORMAT_STEREO16;
+
+        alGenBuffers(1, &this->audioBuffer_);
+        alBufferData(this->audioBuffer_, format, &outbuffer[0], outbuffer.size(), vorbisInfo->rate);
+        ov_clear(&vf);
+
+        if (!alIsBuffer(this->audioBuffer_))
+            ThrowException(General, "Sound: Ogg file loader failed when creating the buffer.");
+    }
+}
Index: code/branches/pickup2/src/orxonox/sound/SoundBuffer.h
===================================================================
--- code/branches/pickup2/src/orxonox/sound/SoundBuffer.h	(revision 6412)
+++ code/branches/pickup2/src/orxonox/sound/SoundBuffer.h	(revision 6412)
@@ -0,0 +1,72 @@
+/*
+ *   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:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _SoundBuffer_H__
+#define _SoundBuffer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include <boost/shared_ptr.hpp>
+#include "core/Resource.h"
+
+namespace orxonox
+{
+    /*
+    @brief
+        The SoundBuffer class is to be used for sounds with position and orientation.
+    */
+    class _OrxonoxExport SoundBuffer
+    {
+        friend class SoundManager;
+        // Make sure nobody deletes an instance (using smart pointers)
+        template <class T>
+        friend void boost::checked_delete(T*);
+
+    public:
+        inline ALuint getBuffer()
+            { return this->audioBuffer_; }
+
+        unsigned int getSize() const;
+
+        const std::string& getFilename() const
+            { return this->filename_; }
+
+    private:
+        SoundBuffer(const std::string& filename, std::list<shared_ptr<SoundBuffer> >::iterator poolIterator);
+        ~SoundBuffer();
+        void loadStandard(const shared_ptr<ResourceInfo>& fileInfo, DataStreamPtr dataStream);
+        void loadOgg(const shared_ptr<ResourceInfo>& fileInfo, DataStreamPtr dataStream);
+
+        std::string filename_;
+        ALuint audioBuffer_;
+        std::list<shared_ptr<SoundBuffer> >::iterator poolIterator_;
+    };
+}
+
+#endif /* _SoundBuffer_H__ */
Index: code/branches/pickup2/src/orxonox/sound/SoundManager.cc
===================================================================
--- code/branches/pickup2/src/orxonox/sound/SoundManager.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/sound/SoundManager.cc	(revision 6412)
@@ -22,4 +22,6 @@
  *   Author:
  *       Erwin 'vaiursch' Herrsche
+ *       Kevin Young
+ *       Reto Grieder
  *   Co-authors:
  *      ...
@@ -30,64 +32,289 @@
 
 #include <AL/alut.h>
+#include <utility>
 
 #include "util/Exception.h"
 #include "util/Math.h"
 #include "util/ScopeGuard.h"
+#include "util/Clock.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
 #include "core/GameMode.h"
 #include "core/ScopedSingletonManager.h"
+#include "core/Resource.h"
+#include "SoundBuffer.h"
+#include "BaseSound.h"
+#include "AmbientSound.h"
+#include "WorldSound.h"
 
 namespace orxonox
 {
-    SoundManager* SoundManager::singletonPtr_s = NULL;
     ManageScopedSingleton(SoundManager, ScopeID::Graphics, true);
 
+    std::string SoundManager::getALErrorString(ALenum code)
+    {
+        switch (code)
+        {
+        case AL_NO_ERROR:          return "No error";
+        case AL_INVALID_NAME:      return "Invalid AL parameter name";
+        case AL_INVALID_ENUM:      return "Invalid AL enum";
+        case AL_INVALID_VALUE:     return "Invalid AL value";
+        case AL_INVALID_OPERATION: return "Invalid AL operation";
+        case AL_OUT_OF_MEMORY:     return "AL reports out of memory";
+        default:                   return "Unknown AL error";
+        }
+    }
+
     SoundManager::SoundManager()
-    {
-        if (!alutInitWithoutContext(NULL,NULL))
-            ThrowException(InitialisationFailed, "OpenAL ALUT error: " << alutGetErrorString(alutGetError()));
+        : effectsPoolSize_(0)
+    {
+        RegisterRootObject(SoundManager);
+
+        // See whether we even want to load
+        bool bDisableSound_ = false;
+        SetConfigValue(bDisableSound_, false);
+        if (bDisableSound_)
+            ThrowException(InitialisationAborted, "Sound: Not loading at all");
+
+        if (!alutInitWithoutContext(NULL, NULL))
+            ThrowException(InitialisationFailed, "Sound Error: ALUT initialisation failed: " << alutGetErrorString(alutGetError()));
         Loki::ScopeGuard alutExitGuard = Loki::MakeGuard(&alutExit);
 
-        COUT(3) << "OpenAL: Opening sound device..." << std::endl;
+/*
+        // Get list of available sound devices and display them
+        const char* devices = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
+        char* device = new char[strlen(devices)+1];
+        strcpy(device, devices);
+        std::string renderDevice;
+        SetConfigValue(renderDevice, std::string(device)).description("Sound device used for rendering");
+        COUT(4) << "Sound: Available devices: ";
+        while (true)
+        {
+            this->deviceNames_.push_back(devices);
+            COUT(4) << '"' << devices << "\", ";
+            devices += strlen(devices) + 1;
+            if (*devices == '\0')
+                break;
+        }
+        COUT(4) << std::endl;
+
+        // Open the selected device
+        COUT(3) << "Sound: Opening device \"" << renderDevice << '\' << std::endl;
+        this->device_ = alcOpenDevice(renderDevice.c_str());
+*/
         this->device_ = alcOpenDevice(NULL);
         if (this->device_ == NULL)
         {
-            COUT(0) << "OpenaAL: Could not open sound device. Have you installed OpenAL?" << std::endl;
+            COUT(1) << "Sound: Could not open sound device. Have you installed OpenAL?" << std::endl;
 #ifdef ORXONOX_PLATFORM_WINDOWS
-            COUT(0) << "Just getting the DLL with the dependencies is not enough for Windows (esp. Windows 7)!" << std::endl;
+            COUT(1) << "Sound: Just getting the DLL with the dependencies is not enough for Windows (esp. Windows 7)!" << std::endl;
 #endif
-            ThrowException(InitialisationFailed, "OpenAL error: Could not open sound device.");
+            ThrowException(InitialisationFailed, "Sound Error: Could not open sound device.");
         }
         Loki::ScopeGuard closeDeviceGuard = Loki::MakeGuard(&alcCloseDevice, this->device_);
 
-        COUT(3) << "OpenAL: Sound device opened" << std::endl;
+        // Create sound context and make it the currently used one
         this->context_ = alcCreateContext(this->device_, NULL);
         if (this->context_ == NULL)
-            ThrowException(InitialisationFailed, "OpenAL error: Could not create sound context");
+            ThrowException(InitialisationFailed, "Sound Error: Could not create ALC context");
         Loki::ScopeGuard desroyContextGuard = Loki::MakeGuard(&alcDestroyContext, this->context_);
-
-        if (alcMakeContextCurrent(this->context_) == AL_TRUE)
-            COUT(3) << "OpenAL: Context " << this->context_ << " loaded" << std::endl;
-
-        COUT(4) << "Sound: OpenAL ALUT version: " << alutGetMajorVersion() << "." << alutGetMinorVersion() << std::endl;
-
-        const char* str = alutGetMIMETypes(ALUT_LOADER_BUFFER);
-        if (str == NULL)
-            COUT(2) << "OpenAL ALUT error: " << alutGetErrorString(alutGetError()) << std::endl;
+        if (!alcMakeContextCurrent(this->context_))
+            ThrowException(InitialisationFailed, "Sound Error: Could not use ALC context");
+
+        GameMode::setPlaysSound(true);
+        Loki::ScopeGuard resetPlaysSoundGuard = Loki::MakeGuard(&GameMode::setPlaysSound, false);
+
+        // Get some information about the sound
+        if (const char* version = alGetString(AL_VERSION))
+            COUT(4) << "Sound: --- OpenAL Version: " << version << std::endl;
+        if (const char* vendor = alGetString(AL_VENDOR))
+            COUT(4) << "Sound: --- OpenAL Vendor : " << vendor << std::endl;
+        if (const char* types = alutGetMIMETypes(ALUT_LOADER_BUFFER))
+            COUT(4) << "Sound: --- Supported MIME Types: " << types << std::endl;
         else
-            COUT(4) << "OpenAL ALUT supported MIME types: " << str << std::endl;
-
-        GameMode::setPlaysSound(true);
+            COUT(2) << "Sound Warning: MIME Type retrieval failed: " << alutGetErrorString(alutGetError()) << std::endl;
+
+        this->mute_[SoundType::All]     = 1.0f;
+        this->mute_[SoundType::Music]   = 1.0f;
+        this->mute_[SoundType::Effects] = 1.0f;
+
+        this->setConfigValues();
+
+        // Try to get at least one source
+        ALuint source;
+        alGenSources(1, &source);
+        if (!alGetError() && alIsSource(source))
+            this->availableSoundSources_.push_back(source);
+        else
+            ThrowException(InitialisationFailed, "Sound Error: Could not create even a single source");
+        // Create a few initial sources
+        this->createSoundSources(this->minSources_ - 1);
+
         // Disarm guards
         alutExitGuard.Dismiss();
         closeDeviceGuard.Dismiss();
         desroyContextGuard.Dismiss();
+        resetPlaysSoundGuard.Dismiss();
+
+        COUT(4) << "Sound: Initialisation complete" << std::endl;
     }
 
     SoundManager::~SoundManager()
     {
+        // Erase fade lists because of the smart pointers
+        this->fadeInList_.clear();
+        this->fadeOutList_.clear();
+
+        // If there are still used buffers around, well, that's just very bad...
+        if (this->soundBuffers_.size() != this->effectsPool_.size())
+            COUT(1) << "Sound Error: Some sound buffers are still in use but OpenAL is about to shut down. Fix this!" << std::endl;
+        // Empty buffer pool and buffer list
+        this->effectsPool_.clear();
+        this->soundBuffers_.clear();
+
+        // There should not be any sources in use anymore
+        if (!this->usedSoundSources_.empty())
+            COUT(1) << "Sound Error: Some sound sources are still in use but OpenAL is about to shut down. Fix this!" << std::endl;
+        while (!this->availableSoundSources_.empty())
+        {
+            alDeleteSources(1, &this->availableSoundSources_.back());
+            this->availableSoundSources_.pop_back();
+        }
+
         GameMode::setPlaysSound(false);
+
+        // Relieve context to destroy it
+        if (!alcMakeContextCurrent(NULL))
+            COUT(1) << "Sound Error: Could not unset ALC context" << std::endl;
         alcDestroyContext(this->context_);
+        if (ALCenum error = alcGetError(this->device_))
+        {
+            if (error == AL_INVALID_OPERATION)
+                COUT(1) << "Sound Error: Could not destroy ALC context because it is the current one" << std::endl;
+            else
+                COUT(1) << "Sound Error: Could not destroy ALC context because it is invalid" << std::endl;
+        }
+#ifdef AL_VERSION_1_1
+        if (!alcCloseDevice(this->device_))
+            COUT(1) << "Sound Error: Could not destroy ALC device. This might be because there are still buffers in use!" << std::endl;
+#else
         alcCloseDevice(this->device_);
-        alutExit();
+#endif
+        if (!alutExit())
+            COUT(1) << "Sound Error: Closing ALUT failed: " << alutGetErrorString(alutGetError()) << std::endl;
+    }
+
+    void SoundManager::setConfigValues()
+    {
+        SetConfigValue(crossFadeStep_, 0.2f)
+            .description("Determines how fast sounds should fade, per second.")
+            .callback(this, &SoundManager::checkFadeStepValidity);
+
+        SetConfigValueAlias(volume_[SoundType::All], "soundVolume_", 1.0f)
+            .description("Defines the overall volume.")
+            .callback(this, &SoundManager::checkSoundVolumeValidity);
+        SetConfigValueAlias(volume_[SoundType::Music], "ambientVolume_", 1.0f)
+            .description("Defines the ambient volume.")
+            .callback(this, &SoundManager::checkAmbientVolumeValidity);
+        SetConfigValueAlias(volume_[SoundType::Effects], "effectsVolume_", 1.0f)
+            .description("Defines the effects volume.")
+            .callback(this, &SoundManager::checkEffectsVolumeValidity);
+
+        SetConfigValue(minSources_, 16)
+            .description("Minimum number of sources being generated (if possible)");
+        SetConfigValue(maxSources_, 1024)
+            .description("Maximum number of sources to be made available");
+    }
+
+    void SoundManager::preUpdate(const Clock& time)
+    {
+        this->processCrossFading(time.getDeltaTime());
+
+        // Check whether a sound object has stopped playing
+        for (unsigned int i = 0; i < this->usedSoundSources_.size(); ++i)
+        {
+            ALint state;
+            alGetSourcei(this->usedSoundSources_[i].first, AL_SOURCE_STATE, &state);
+            if (state == AL_STOPPED)
+            {
+                this->usedSoundSources_[i].second->stop();
+                --i;
+            }
+        }
+    }
+
+    void SoundManager::checkFadeStepValidity()
+    {
+        if (crossFadeStep_ <= 0.0 || crossFadeStep_ >= 1.0 )
+        {
+            COUT(2) << "Sound warning: fade step out of range, ignoring change." << std::endl;
+            ResetConfigValue(crossFadeStep_);
+        }
+    }
+
+    void SoundManager::checkVolumeValidity(SoundType::Value type)
+    {
+        float clampedVolume = clamp(this->volume_[type], 0.0f, 1.0f);
+        if (clampedVolume != this->volume_[type])
+            COUT(2) << "Sound warning: Volume setting (" << type << ") out of range, clamping." << std::endl;
+        this->updateVolume(type);
+    }
+
+    void SoundManager::setVolume(float vol, SoundType::Value type)
+    {
+        if (type < 0 || type > SoundType::Effects)
+            return;
+        this->volume_[type] = vol;
+        this->checkVolumeValidity(type);
+    }
+
+    float SoundManager::getVolume(SoundType::Value type)
+    {
+        if (type < 0 || type > SoundType::Effects)
+            return 0.0f;
+        return this->volume_[type];
+    }
+
+    float SoundManager::getRealVolume(SoundType::Value type)
+    {
+        if (type != SoundType::Music && type != SoundType::Effects)
+            return 0.0f;
+        return this->volume_[SoundType::All] * this->mute_[SoundType::All] * this->volume_[type] * this->mute_[type];
+    }
+
+    void SoundManager::updateVolume(SoundType::Value type)
+    {
+        switch(type)
+        {
+        case SoundType::All:
+            for (ObjectList<BaseSound>::iterator it = ObjectList<BaseSound>::begin(); it != ObjectList<BaseSound>::end(); ++it)
+                (*it)->updateVolume();
+            break;
+        case SoundType::Music:
+            for (ObjectList<AmbientSound>::iterator it = ObjectList<AmbientSound>::begin(); it != ObjectList<AmbientSound>::end(); ++it)
+                (*it)->updateVolume();
+            break;
+        case SoundType::Effects:
+            for (ObjectList<WorldSound>::iterator it = ObjectList<WorldSound>::begin(); it != ObjectList<WorldSound>::end(); ++it)
+                (*it)->updateVolume();
+            break;
+        default:
+            assert(false);
+        }
+    }
+
+    void SoundManager::toggleMute(SoundType::Value type)
+    {
+        if (type < 0 || type > SoundType::Effects)
+            return;
+        this->mute_[type] = (this->mute_[type] == 0) ? 1.0f : 0.0f;
+        this->updateVolume(type);
+    }
+
+    bool SoundManager::getMute(SoundType::Value type)
+    {
+        if (type < 0 || type > SoundType::Effects)
+            return true;
+        return (this->mute_[type] == 0);
     }
 
@@ -103,14 +330,310 @@
     {
         // update listener orientation
-        Vector3 up = orientation.xAxis(); // just a wild guess
-        Vector3 at = orientation.zAxis();
-
-        ALfloat orient[6] = { at.x, at.y, at.z,
-                              up.x, up.y, up.z };
-
-        alListenerfv(AL_POSITION, orient);
+        const Vector3& direction = -orientation.zAxis();
+        const Vector3& up = orientation.yAxis();
+
+        ALfloat orient[6] = { direction.x, direction.y, direction.z, up.x, up.y, up.z };
+
+        alListenerfv(AL_ORIENTATION, orient);
         ALenum error = alGetError();
         if (error == AL_INVALID_VALUE)
             COUT(2) << "Sound: OpenAL: Invalid listener orientation" << std::endl;
     }
+
+    void SoundManager::registerAmbientSound(AmbientSound* newAmbient)
+    {
+        if (newAmbient != NULL)
+        {
+            for (AmbientList::const_iterator it = this->ambientSounds_.begin(); it != this->ambientSounds_.end(); ++it)
+            {
+                if (it->first == newAmbient)
+                {
+                    COUT(2) << "Sound warning: Will not play an AmbientSound twice." << std::endl;
+                    return;
+                }
+            }
+
+            if (!this->ambientSounds_.empty())
+            {
+                this->fadeOut(ambientSounds_.front().first);
+            }
+            this->ambientSounds_.push_front(std::make_pair(newAmbient, false));
+            newAmbient->doPlay();
+            this->fadeIn(newAmbient);
+        }
+    }
+
+    void SoundManager::unregisterAmbientSound(AmbientSound* oldAmbient)
+    {
+        if (oldAmbient == NULL || ambientSounds_.empty())
+            return;
+
+        if (this->ambientSounds_.front().first == oldAmbient)
+        {
+            this->fadeOut(oldAmbient);
+            this->ambientSounds_.pop_front();
+            if (!this->ambientSounds_.empty())
+            {
+                if (!this->ambientSounds_.front().second) // Not paused before
+                {
+                    this->ambientSounds_.front().first->doPlay();
+                }
+                this->fadeIn(this->ambientSounds_.front().first);
+            }
+        }
+        else
+        {
+            for (AmbientList::iterator it = this->ambientSounds_.begin(); it != this->ambientSounds_.end(); ++it)
+            {
+                if (it->first == oldAmbient)
+                {
+                    this->fadeOut(oldAmbient);
+                    this->ambientSounds_.erase(it);
+                    break;
+                }
+            }
+        }
+    }
+
+    void SoundManager::pauseAmbientSound(AmbientSound* ambient)
+    {
+        if (ambient != NULL)
+        {
+            for (AmbientList::iterator it = this->ambientSounds_.begin(); it != this->ambientSounds_.end(); ++it)
+            {
+                if (it->first == ambient)
+                {
+                    it->second = true;
+                    this->fadeOut(it->first);
+                    return;
+                }
+            }
+        }
+    }
+
+    void SoundManager::fadeIn(const SmartPtr<AmbientSound>& sound)
+    {
+        // If we're already fading out --> remove that
+        for (std::list<SmartPtr<AmbientSound> >::iterator it = this->fadeOutList_.begin(); it != this->fadeOutList_.end(); it++)
+        {
+            if (*it == sound)
+            {
+                this->fadeOutList_.erase(it);
+                break;
+            }
+        }
+        // No duplicate entries
+        if (std::find(this->fadeInList_.begin(), this->fadeInList_.end(), sound) == this->fadeInList_.end())
+            this->fadeInList_.push_back(sound);
+    }
+
+    void SoundManager::fadeOut(const SmartPtr<AmbientSound>& sound)
+    {
+        // If we're already fading in --> remove that
+        for (std::list<SmartPtr<AmbientSound> >::iterator it = this->fadeInList_.begin(); it != this->fadeInList_.end(); it++)
+        {
+            if (*it == sound)
+            {
+                this->fadeInList_.erase(it);
+                break;
+            }
+        }
+        // No duplicate entries
+        if (std::find(this->fadeOutList_.begin(), this->fadeOutList_.end(), sound) == this->fadeOutList_.end())
+            this->fadeOutList_.push_back(sound);
+    }
+
+    void SoundManager::processCrossFading(float dt)
+    {
+
+        // Hacky solution to the fade delay while loading a level.
+        if(dt > 0.2)
+        {
+            return;
+        }
+
+        // FADE IN
+        for (std::list<SmartPtr<AmbientSound> >::iterator it= this->fadeInList_.begin(); it != this->fadeInList_.end(); )
+        {
+            if ((*it)->getVolume() + this->crossFadeStep_*dt > 1.0f)
+            {
+                (*it)->setVolume(1.0f);
+                this->fadeInList_.erase(it++);
+            }
+            else
+            {
+                (*it)->setVolume((*it)->getVolume() + this->crossFadeStep_*dt);
+                ++it;
+            }
+        }
+
+        // FADE OUT
+        for (std::list<SmartPtr<AmbientSound> >::iterator it = this->fadeOutList_.begin(); it != this->fadeOutList_.end(); )
+        {
+            if ((*it)->getVolume() - this->crossFadeStep_*dt < 0.0f)
+            {
+                (*it)->setVolume(0.0f);
+
+                // If sound is in the ambient list --> pause
+                for (AmbientList::const_iterator it2 = this->ambientSounds_.begin(); it2 != this->ambientSounds_.end(); ++it2)
+                {
+                    if (it2->first == *it)
+                    {
+                        (*it)->doPause();
+                        break;
+                    }
+                }
+                // If not pause (by loop above for instance) --> stop
+                if (!(*it)->isPaused())
+                    (*it)->doStop();
+
+                this->fadeOutList_.erase(it++);
+            }
+            else
+            {
+                (*it)->setVolume((*it)->getVolume() - this->crossFadeStep_*dt);
+                ++it;
+            }
+        }
+    }
+
+    shared_ptr<SoundBuffer> SoundManager::getSoundBuffer(const std::string& filename)
+    {
+        shared_ptr<SoundBuffer> buffer;
+        // Check active or pooled buffers
+        SoundBufferMap::const_iterator it = this->soundBuffers_.find(filename);
+        if (it != this->soundBuffers_.end())
+        {
+            buffer = it->second;
+
+            // Remove from effects pool if not active used before
+            if (buffer->poolIterator_ != this->effectsPool_.end())
+            {
+                this->effectsPoolSize_ -= buffer->getSize();
+                this->effectsPool_.erase(buffer->poolIterator_);
+                buffer->poolIterator_ = this->effectsPool_.end();
+            }
+        }
+        else
+        {
+            try
+            {
+                buffer.reset(new SoundBuffer(filename, this->effectsPool_.end()));
+            }
+            catch (...)
+            {
+                COUT(1) << Exception::handleMessage() << std::endl;
+                return buffer;
+            }
+            this->soundBuffers_[filename] = buffer;
+        }
+        return buffer;
+    }
+
+    void SoundManager::releaseSoundBuffer(const shared_ptr<SoundBuffer>& buffer, bool bPoolBuffer)
+    {
+        // Check if others are still using the buffer
+        if (buffer.use_count() != 2)
+            return;
+        SoundBufferMap::iterator it = this->soundBuffers_.find(buffer->getFilename());
+        if (it != this->soundBuffers_.end())
+        {
+            if (bPoolBuffer)
+            {
+                // Pool already too large?
+                while (this->effectsPoolSize_ + it->second->getSize() > this->maxEffectsPoolSize_s && !this->effectsPool_.empty())
+                {
+                    shared_ptr<SoundBuffer> bufferDel = this->effectsPool_.back();
+                    this->effectsPoolSize_ -= bufferDel->getSize();
+                    bufferDel->poolIterator_ = this->effectsPool_.end();
+                    this->effectsPool_.pop_back();
+                    // Remove from buffer map too
+                    SoundBufferMap::iterator itDel = this->soundBuffers_.find(bufferDel->getFilename());
+                    if (itDel != this->soundBuffers_.end())
+                        this->soundBuffers_.erase(itDel);
+                }
+                // Put buffer into the pool
+                this->effectsPoolSize_ += it->second->getSize();
+                this->effectsPool_.push_front(it->second);
+                it->second->poolIterator_ = this->effectsPool_.begin();
+            }
+            else
+                this->soundBuffers_.erase(it);
+        }
+    }
+
+    ALuint SoundManager::getSoundSource(BaseSound* object)
+    {
+        if (!this->availableSoundSources_.empty())
+        {
+            ALuint source = this->availableSoundSources_.back();
+            this->availableSoundSources_.pop_back();
+            this->usedSoundSources_.push_back(std::make_pair(source, object));
+            return source;
+        }
+        else
+        {
+            if (this->usedSoundSources_.size() < this->maxSources_)
+            {
+                ALuint source;
+                alGenSources(1, &source);
+                // Try to create new sources (50% more, but at least one)
+                if (alIsSource(source) && !alGetError())
+                {
+                    this->usedSoundSources_.push_back(std::make_pair(source, object));
+                    return source;
+                }
+            }
+            // Return no source ID
+            ALuint source = 123456789;
+            while (alIsSource(++source));
+            return source;
+        }
+    }
+
+    void SoundManager::releaseSoundSource(ALuint source)
+    {
+#ifndef NDEBUG
+        for (std::vector<ALuint>::const_iterator it = this->availableSoundSources_.begin(); it != this->availableSoundSources_.end(); ++it)
+            assert((*it) != source);
+#endif
+        this->availableSoundSources_.push_back(source);
+        for (std::vector<std::pair<ALuint, BaseSound*> >::iterator it = this->usedSoundSources_.begin();
+            it != this->usedSoundSources_.end(); ++it)
+        {
+            if (it->first == source)
+            {
+                this->usedSoundSources_.erase(it);
+                break;
+            }
+        }
+        int used = std::max(this->usedSoundSources_.size(), this->minSources_);
+        // Subtract those we added in the statement above trough std::max
+        int available = (int)this->availableSoundSources_.size() - (used - (int)this->usedSoundSources_.size());
+        // Delete sources again to free resources if appropriate (more than 50% more available than used)
+        int toDelete = available - used / 2;
+        while (toDelete-- > 0)
+        {
+            alDeleteSources(1, &this->availableSoundSources_.back());
+            if (alGetError())
+                COUT(1) << "Sound Error: Failed to delete a source --> lost forever" << std::endl;
+            this->availableSoundSources_.pop_back();
+        }
+    }
+
+    unsigned int SoundManager::createSoundSources(unsigned int n)
+    {
+        unsigned int count = this->availableSoundSources_.size() + this->usedSoundSources_.size();
+        while (count < this->maxSources_ && count <= n)
+        {
+            ALuint source;
+            alGenSources(1, &source);
+            if (alIsSource(source) && !alGetError())
+                this->availableSoundSources_.push_back(source);
+            else
+                break;
+            ++count;
+        }
+        return count - this->availableSoundSources_.size() - this->usedSoundSources_.size();
+    }
 }
Index: code/branches/pickup2/src/orxonox/sound/SoundManager.h
===================================================================
--- code/branches/pickup2/src/orxonox/sound/SoundManager.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/sound/SoundManager.h	(revision 6412)
@@ -22,7 +22,10 @@
  *   Author:
  *       Erwin 'vaiursch' Herrsche
+ *       Kevin Young
+ *       Reto Grieder
  *   Co-authors:
  *      ...
  */
+
 #ifndef _SoundManager_H__
 #define _SoundManager_H__
@@ -30,33 +33,121 @@
 #include "OrxonoxPrereqs.h"
 
-#include <cassert>
 #include <list>
+#include <map>
+#include <string>
+#include <boost/shared_ptr.hpp>
+
 #include "util/Singleton.h"
-#include "tools/interfaces/Tickable.h"
+#include "core/OrxonoxClass.h"
+#include "core/SmartPtr.h"
 
+// tolua_begin
 namespace orxonox
 {
-    /**
-     * The SoundManager class manages the OpenAL device, context and listener
-     * position. It is a singleton.
-     *
-     */
-    class _OrxonoxExport SoundManager : public Singleton<SoundManager>
+    //! Enum for the sound type.
+    namespace SoundType
     {
+        enum Value
+        {
+            All     = 0,
+            Music   = 1,
+            Effects = 2
+        };
+    }
+
+    //! The SoundManager class manages the OpenAL device, context and listener position.
+    class _OrxonoxExport SoundManager
+    // tolua_end
+        : public Singleton<SoundManager>, public OrxonoxClass
+    { // tolua_export
         friend class Singleton<SoundManager>;
+
     public:
         SoundManager();
         ~SoundManager();
 
+        void preUpdate(const Clock& time);
+        void setConfigValues();
+
+        // tolua_begin
+        static SoundManager& getInstance() { return Singleton<SoundManager>::getInstance(); }
+
+        std::string getDeviceName(unsigned int index) const
+            { return index < this->deviceNames_.size() ? this->deviceNames_[index] : std::string(); }
+        // tolua_end
+
         void setListenerPosition(const Vector3& position);
         void setListenerOrientation(const Quaternion& orientation);
 
+        void registerAmbientSound(AmbientSound* newAmbient);
+        void unregisterAmbientSound(AmbientSound* oldAmbient);
+        void pauseAmbientSound(AmbientSound* ambient);
+
+        // tolua_begin
+        void setVolume(float vol, SoundType::Value type);
+        float getVolume(SoundType::Value type);
+        float getRealVolume(SoundType::Value type);
+
+        void toggleMute(SoundType::Value type);
+        bool getMute(SoundType::Value type);
+        // tolua_end
+
+        shared_ptr<SoundBuffer> getSoundBuffer(const std::string& filename);
+        void releaseSoundBuffer(const shared_ptr<SoundBuffer>& buffer, bool bPoolBuffer);
+
+        ALuint getSoundSource(BaseSound* object);
+        void releaseSoundSource(ALuint source);
+
+        static std::string getALErrorString(ALenum error);
+
     private:
+        void processCrossFading(float dt);
+        void fadeIn(const SmartPtr<AmbientSound>& sound);
+        void fadeOut(const SmartPtr<AmbientSound>& sound);
+
+        void checkFadeStepValidity();
+
+        void checkVolumeValidity(SoundType::Value type);
+        void checkSoundVolumeValidity()   { this->checkVolumeValidity(SoundType::All); }
+        void checkAmbientVolumeValidity() { this->checkVolumeValidity(SoundType::Music); }
+        void checkEffectsVolumeValidity() { this->checkVolumeValidity(SoundType::Effects); }
+        void updateVolume(SoundType::Value type);
+
+        unsigned int createSoundSources(unsigned int n);
+
+        // OpenAL device/context related
+        std::vector<std::string> deviceNames_;
         ALCdevice* device_;
         ALCcontext* context_;
 
+        // Ambient sound related
+        typedef std::list<std::pair<AmbientSound*, bool> > AmbientList;
+        AmbientList                        ambientSounds_;
+        //! Absolute change per second (0.1 means 10% of the nominal volume) for cross fading
+        float                              crossFadeStep_;
+        std::list<SmartPtr<AmbientSound> > fadeInList_;
+        std::list<SmartPtr<AmbientSound> > fadeOutList_;
+
+        // Volume related
+        float volume_[3];
+        float mute_[3];
+
+        // Sound buffer related
+        static const unsigned int maxEffectsPoolSize_s = 40 * 1024 * 1024;
+        unsigned int effectsPoolSize_;
+        typedef std::list<shared_ptr<SoundBuffer> > EffectsPoolList;
+        EffectsPoolList effectsPool_;
+        typedef std::map<std::string, shared_ptr<SoundBuffer> > SoundBufferMap;
+        SoundBufferMap soundBuffers_;
+
+        // Sound source related
+        unsigned int minSources_;
+        unsigned int maxSources_;
+        std::vector<ALuint> availableSoundSources_;
+        std::vector<std::pair<ALuint, BaseSound*> > usedSoundSources_;
+
         static SoundManager* singletonPtr_s;
-    };
-}
+    }; // tolua_export
+} // tolua_export
 
 #endif /* _SoundManager_H__ */
Index: code/branches/pickup2/src/orxonox/sound/SoundStreamer.cc
===================================================================
--- code/branches/pickup2/src/orxonox/sound/SoundStreamer.cc	(revision 6412)
+++ code/branches/pickup2/src/orxonox/sound/SoundStreamer.cc	(revision 6412)
@@ -0,0 +1,128 @@
+/*
+ *   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:
+ *      Erwin 'vaiursch' Herrsche
+ *   Co-authors:
+ *
+ */
+#include "SoundStreamer.h"
+
+#include <al.h>
+#include <vorbis/vorbisfile.h>
+#include "SoundManager.h"
+
+namespace orxonox
+{
+    // vorbis callbacks
+    size_t readVorbis(void* ptr, size_t size, size_t nmemb, void* datasource);
+    int seekVorbis(void* datasource, ogg_int64_t offset, int whence);
+    long tellVorbis(void* datasource);
+
+    void orxonox::SoundStreamer::operator()(ALuint audioSource, DataStreamPtr dataStream)
+    {
+        // Open file with custom streaming
+        ov_callbacks vorbisCallbacks;
+        vorbisCallbacks.read_func  = &readVorbis;
+        vorbisCallbacks.seek_func  = &seekVorbis;
+        vorbisCallbacks.tell_func  = &tellVorbis;
+        vorbisCallbacks.close_func = NULL;
+
+        OggVorbis_File vf;
+        int ret = ov_open_callbacks(dataStream.get(), &vf, NULL, 0, vorbisCallbacks);
+        if (ret < 0)
+        {
+            COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
+            ov_clear(&vf);
+            return;
+        }
+        vorbis_info* vorbisInfo;
+        vorbisInfo = ov_info(&vf, -1);
+        ALenum format;
+        if (vorbisInfo->channels == 1)
+            format = AL_FORMAT_MONO16;
+        else
+            format = AL_FORMAT_STEREO16;
+
+        char inbuffer[256*1024];
+        ALuint initbuffers[4];
+        alGenBuffers(4, initbuffers);
+        int current_section;
+
+        for(int i = 0; i < 4; i++)
+        {
+            long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
+            if (ret == 0)
+            {
+                return;
+            }
+            else if (ret < 0)
+            {
+                COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
+                ov_clear(&vf);
+                return;
+            }
+
+            alBufferData(initbuffers[i], format, &inbuffer, ret, vorbisInfo->rate);
+        }
+        alSourceQueueBuffers(audioSource, 4, initbuffers);
+
+        while(true) // Stream forever, control through thread control
+        {
+            int processed;
+            alGetSourcei(audioSource, AL_BUFFERS_PROCESSED, &processed);
+            if (ALint error = alGetError())
+            COUT(2) << "Sound Warning: Couldn't get number of processed buffers: "
+                    << SoundManager::getALErrorString(error) << std::endl;
+
+            if(processed > 0)
+            {
+                ALuint* buffers = new ALuint[processed];
+                alSourceUnqueueBuffers(audioSource, processed, buffers);
+                if (ALint error = alGetError())
+                    COUT(2) << "Sound Warning: Couldn't unqueue buffers: "
+                    << SoundManager::getALErrorString(error) << std::endl;
+
+                for(int i = 0; i < processed; i++)
+                {
+                    long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
+                    if (ret == 0)
+                    {
+                        return;
+                    }
+                    else if (ret < 0)
+                    {
+                        COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
+                        ov_clear(&vf);
+                        return;
+                    }
+
+                    alBufferData(buffers[i], format, &inbuffer, ret, vorbisInfo->rate);
+                }
+
+                alSourceQueueBuffers(audioSource, processed, buffers);
+                if (ALint error = alGetError())
+                    COUT(2) << "Sound Warning: Couldn't queue buffers: "
+                    << SoundManager::getALErrorString(error) << std::endl;
+            }
+        }
+    }
+}
Index: code/branches/pickup2/src/orxonox/sound/SoundStreamer.h
===================================================================
--- code/branches/pickup2/src/orxonox/sound/SoundStreamer.h	(revision 6412)
+++ code/branches/pickup2/src/orxonox/sound/SoundStreamer.h	(revision 6412)
@@ -0,0 +1,46 @@
+/*
+ *   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:
+ *      Erwin 'vaiursch' Herrsche
+ *   Co-authors:
+ *
+ */
+
+#ifndef _SoundStreamer_H__
+#define _SoundStreamer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include <OgreDataStream.h>
+#include "core/CorePrereqs.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport SoundStreamer // class for stream threads
+    {
+    public:
+        void operator()(ALuint audioSource, DataStreamPtr dataStream);
+    };
+}
+
+#endif /* _SoundStreamer_H__ */
Index: code/branches/pickup2/src/orxonox/sound/WorldSound.cc
===================================================================
--- code/branches/pickup2/src/orxonox/sound/WorldSound.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/sound/WorldSound.cc	(revision 6412)
@@ -35,4 +35,7 @@
 #include "core/EventIncludes.h"
 #include "core/XMLPort.h"
+#include "Scene.h"
+#include "SoundManager.h"
+#include <core/ConsoleCommandCompilation.h>
 
 namespace orxonox
@@ -44,8 +47,16 @@
     {
         RegisterObject(WorldSound);
+        // WorldSound buffers should be pooled when they're not used anymore
+        this->bPooling_ = true;
+        this->registerVariables();
     }
 
-    WorldSound::~WorldSound()
+    void WorldSound::registerVariables()
     {
+        registerVariable(volume_,   ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::volumeChanged));
+        registerVariable(source_,   ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::sourceChanged));
+        registerVariable(bLooping_, ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::loopingChanged));
+        registerVariable(pitch_,    ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::pitchChanged));
+        registerVariable((int&)(BaseSound::state_), ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::stateChanged));
     }
 
@@ -53,7 +64,5 @@
     {
         SUPER(WorldSound, XMLPort, xmlelement, mode);
-        XMLPortParamExtern(WorldSound, BaseSound, this, "source", setSource, getSource, xmlelement, mode);
-        XMLPortParamExtern(WorldSound, BaseSound, this, "loop", setLoop, getLoop, xmlelement, mode);
-        XMLPortParamExtern(WorldSound, BaseSound, this, "playOnLoad", setPlayOnLoad, getPlayOnLoad, xmlelement, mode);
+        BaseSound::XMLPortExtern(xmlelement, mode);
     }
 
@@ -62,4 +71,17 @@
         SUPER(WorldSound, XMLEventPort, xmlelement, mode);
         XMLPortEventState(WorldSound, BaseObject, "play", play, xmlelement, mode);
+    }
+
+    void WorldSound::initialiseSource()
+    {
+        BaseSound::initialiseSource();
+        if (this->getScene())
+        {
+            float refDist = this->getScene()->getSoundReferenceDistance();
+            alSourcef(this->audioSource_, AL_REFERENCE_DISTANCE, refDist);
+            // TODO: 500 is very magical here. Derive something better
+            alSourcef(this->audioSource_, AL_MAX_DISTANCE, refDist * 500);
+        }
+        this->tick(0); // update position, orientation and velocity
     }
 
@@ -80,7 +102,6 @@
                 COUT(2) << "Sound: OpenAL: Invalid sound velocity" << std::endl;
 
-            const Quaternion& orient = this->getWorldOrientation();
-            Vector3 at = orient.zAxis();
-            alSource3f(this->audioSource_, AL_DIRECTION, at.x, at.y, at.z);
+            const Vector3& direction = -this->getWorldOrientation().zAxis();
+            alSource3f(this->audioSource_, AL_DIRECTION, direction.x, direction.y, direction.z);
             error = alGetError();
             if (error == AL_INVALID_VALUE)
@@ -89,3 +110,17 @@
     }
 
+    void WorldSound::changedActivity()
+    {
+        SUPER(WorldSound, changedActivity);
+        if (this->isActive())
+            this->play();
+        else
+            this->stop();
+    }
+
+    float WorldSound::getRealVolume()
+    {
+        assert(GameMode::playsSound());
+        return SoundManager::getInstance().getRealVolume(SoundType::Effects);
+    }
 }
Index: code/branches/pickup2/src/orxonox/sound/WorldSound.h
===================================================================
--- code/branches/pickup2/src/orxonox/sound/WorldSound.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/sound/WorldSound.h	(revision 6412)
@@ -26,4 +26,5 @@
  *
  */
+
 #ifndef _WorldSound_H__
 #define _WorldSound_H__
@@ -45,12 +46,18 @@
     public:
         WorldSound(BaseObject* creator);
-        virtual ~WorldSound();
 
-        virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-        virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+        void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+        void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+        void changedActivity();
 
-        virtual void tick(float dt);
+        void tick(float dt);
+
+    protected:
+        ~WorldSound() {}
 
     private:
+        void registerVariables();
+        void initialiseSource();
+        float getRealVolume();
     };
 }
Index: code/branches/pickup2/src/orxonox/weaponsystem/WeaponMode.cc
===================================================================
--- code/branches/pickup2/src/orxonox/weaponsystem/WeaponMode.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/weaponsystem/WeaponMode.cc	(revision 6412)
@@ -32,4 +32,6 @@
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
+#include "controllers/Controller.h"
+#include "worldentities/pawns/Pawn.h"
 
 #include "Munition.h"
@@ -37,4 +39,7 @@
 #include "WeaponPack.h"
 #include "WeaponSystem.h"
+#include "WeaponSlot.h"
+
+#include "sound/WorldSound.h"
 
 namespace orxonox
@@ -61,9 +66,26 @@
 
         this->damage_ = 0;
+
         this->muzzleOffset_ = Vector3::ZERO;
+        this->muzzlePosition_ = Vector3::ZERO;
+        this->muzzleOrientation_ = Quaternion::IDENTITY;
+
+        if( GameMode::isMaster() )
+        {
+            this->defSndWpnFire_ = new WorldSound(this);
+            this->defSndWpnFire_->setLooping(false);
+            this->bSoundAttached_ = false;
+        }
+        else
+            this->defSndWpnFire_ = 0;
     }
 
     WeaponMode::~WeaponMode()
     {
+        if (this->isInitialized())
+        {
+            if (this->defSndWpnFire_)
+                this->defSndWpnFire_->destroy();
+        }
     }
 
@@ -90,4 +112,10 @@
     {
         (*reloadTime) = this->reloadTime_;
+        if( !this->bSoundAttached_ && GameMode::isMaster() )
+        {
+            assert(this->getWeapon());
+            this->getWeapon()->attach(this->defSndWpnFire_);
+            this->bSoundAttached_ = true;
+        }
 
         if (!this->bReloading_ && this->munition_ && this->munition_->takeMunition(this->munitionPerShot_, this))
@@ -108,4 +136,9 @@
             this->reloadTimer_.startTimer();
 
+            if( this->defSndWpnFire_ && !(this->defSndWpnFire_->isPlaying()))
+            {
+                this->defSndWpnFire_->play();
+            }
+
             this->fire();
 
@@ -145,5 +178,9 @@
     {
         this->munitionname_ = munitionname;
-        this->munitiontype_ = ClassByString(this->munitionname_);
+        Identifier* identifier = ClassByString(this->munitionname_);
+        if (identifier)
+            this->munitiontype_ = identifier;
+        else
+            COUT(2) << "Warning: No munition class defined in WeaponMode " << this->getName() << std::endl;
         this->updateMunition();
     }
@@ -191,29 +228,49 @@
     void WeaponMode::reloaded()
     {
+        if( this->defSndWpnFire_ && this->defSndWpnFire_->isPlaying())
+        {
+            this->defSndWpnFire_->stop();
+        }
         this->bReloading_ = false;
     }
 
-    Vector3 WeaponMode::getMuzzlePosition() const
+    void WeaponMode::computeMuzzleParameters(const Vector3& target)
     {
         if (this->weapon_)
-            return (this->weapon_->getWorldPosition() + this->weapon_->getWorldOrientation() * this->muzzleOffset_);
-        else
-            return this->muzzleOffset_;
-    }
-
-    const Quaternion& WeaponMode::getMuzzleOrientation() const
+        {
+            this->muzzlePosition_ = this->weapon_->getWorldPosition() + this->weapon_->getWorldOrientation() * this->muzzleOffset_;
+
+            Vector3 muzzleDirection;
+            muzzleDirection = target - this->muzzlePosition_;
+//             COUT(0) << "muzzleDirection " << muzzleDirection << endl;
+            this->muzzleOrientation_ = (this->weapon_->getWorldOrientation() * WorldEntity::FRONT).getRotationTo(muzzleDirection) * this->weapon_->getWorldOrientation();
+        }
+        else
+        {
+            this->muzzlePosition_ = this->muzzleOffset_;
+            this->muzzleOrientation_ = Quaternion::IDENTITY;
+        }
+    }
+
+    Vector3 WeaponMode::getMuzzleDirection() const
     {
         if (this->weapon_)
-            return this->weapon_->getWorldOrientation();
-        else
-            return Quaternion::IDENTITY;
-    }
-
-    Vector3 WeaponMode::getMuzzleDirection() const
-    {
-        if (this->weapon_)
-            return (this->weapon_->getWorldOrientation() * WorldEntity::FRONT);
+            return (this->getMuzzleOrientation() * WorldEntity::FRONT);
         else
             return WorldEntity::FRONT;
     }
+
+    void WeaponMode::setDefaultSound(const std::string& soundPath)
+    {
+        if( this->defSndWpnFire_ )
+            this->defSndWpnFire_->setSource(soundPath);
+    }
+
+    const std::string& WeaponMode::getDefaultSound()
+    {
+        if( this->defSndWpnFire_ )
+            return this->defSndWpnFire_->getSource();
+        else
+            return BLANKSTRING;
+    }
 }
Index: code/branches/pickup2/src/orxonox/weaponsystem/WeaponMode.h
===================================================================
--- code/branches/pickup2/src/orxonox/weaponsystem/WeaponMode.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/weaponsystem/WeaponMode.h	(revision 6412)
@@ -51,4 +51,8 @@
             bool fire(float* reloadTime);
             bool reload();
+
+            // Interacting with the default Firing sound
+            void setDefaultSound(const std::string& soundPath);
+            const std::string& getDefaultSound();
 
 
@@ -109,6 +113,9 @@
                 { return this->muzzleOffset_; }
 
-            Vector3 getMuzzlePosition() const;
-            const Quaternion& getMuzzleOrientation() const;
+            void computeMuzzleParameters(const Vector3& target);
+            const Vector3& getMuzzlePosition() const
+                { return this->muzzlePosition_; }
+            const Quaternion& getMuzzleOrientation() const
+                { return this->muzzleOrientation_; }
             Vector3 getMuzzleDirection() const;
 
@@ -124,4 +131,6 @@
             inline unsigned int getMode() const
                 { return this->mode_; }
+
+            Vector3 getTarget();
 
         protected:
@@ -152,4 +161,10 @@
             Timer reloadTimer_;
             bool bReloading_;
+
+            Vector3 muzzlePosition_;
+            Quaternion muzzleOrientation_;
+
+            WorldSound* defSndWpnFire_;
+            bool        bSoundAttached_;
     };
 }
Index: code/branches/pickup2/src/orxonox/weaponsystem/WeaponPack.cc
===================================================================
--- code/branches/pickup2/src/orxonox/weaponsystem/WeaponPack.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/weaponsystem/WeaponPack.cc	(revision 6412)
@@ -49,7 +49,8 @@
     WeaponPack::~WeaponPack()
     {
-        if (this->isInitialized() && this->weaponSystem_)
+        if (this->isInitialized())
         {
-            this->weaponSystem_->removeWeaponPack(this);
+            if( this->weaponSystem_ )
+                this->weaponSystem_->removeWeaponPack(this);
 
             while (!this->weapons_.empty())
@@ -71,5 +72,5 @@
     void WeaponPack::fire(unsigned int weaponmode)
     {
-        for (std::set<Weapon *>::iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
+        for (std::vector<Weapon *>::iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
             (*it)->fire(weaponmode);
     }
@@ -77,5 +78,5 @@
     void WeaponPack::reload()
     {
-        for (std::set<Weapon *>::iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
+        for (std::vector<Weapon *>::iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
             (*it)->reload();
     }
@@ -86,5 +87,5 @@
             return;
 
-        this->weapons_.insert(weapon);
+        this->weapons_.push_back(weapon);
         weapon->setWeaponPack(this);
     }
@@ -95,5 +96,7 @@
             return;
 
-        this->weapons_.erase(weapon);
+        std::vector<Weapon*>::iterator it = std::find(this->weapons_.begin(), this->weapons_.end(), weapon);
+        assert(it != this->weapons_.end());
+        this->weapons_.erase(it);
         weapon->setWeaponPack(0);
     }
@@ -103,5 +106,5 @@
         unsigned int i = 0;
 
-        for (std::set<Weapon *>::const_iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
+        for (std::vector<Weapon *>::const_iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
         {
             if (i == index)
@@ -142,5 +145,5 @@
     void WeaponPack::notifyWeapons()
     {
-        for (std::set<Weapon *>::const_iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
+        for (std::vector<Weapon *>::const_iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
             (*it)->setWeaponPack(this);
     }
Index: code/branches/pickup2/src/orxonox/weaponsystem/WeaponPack.h
===================================================================
--- code/branches/pickup2/src/orxonox/weaponsystem/WeaponPack.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/weaponsystem/WeaponPack.h	(revision 6412)
@@ -69,5 +69,5 @@
             void notifyWeapons();
 
-            std::set<Weapon *> weapons_;
+            std::vector<Weapon *> weapons_;
             std::set<DefaultWeaponmodeLink *> links_;
             WeaponSystem * weaponSystem_;
Index: code/branches/pickup2/src/orxonox/weaponsystem/WeaponSystem.cc
===================================================================
--- code/branches/pickup2/src/orxonox/weaponsystem/WeaponSystem.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/weaponsystem/WeaponSystem.cc	(revision 6412)
@@ -202,5 +202,5 @@
         }
 
-        this->weaponPacks_.insert(wPack);
+        this->weaponPacks_.push_back(wPack);
         wPack->setWeaponSystem(this);
 
@@ -221,5 +221,7 @@
 
         // Remove the WeaponPack from the WeaponSystem
-        this->weaponPacks_.erase(wPack);
+        std::vector<WeaponPack*>::iterator it = std::find(this->weaponPacks_.begin(),this->weaponPacks_.end(), wPack);
+        assert(it !=this->weaponPacks_.end());
+        this->weaponPacks_.erase(it);
     }
 
@@ -227,5 +229,5 @@
     {
         unsigned int i = 0;
-        for (std::set<WeaponPack*>::const_iterator it = this->weaponPacks_.begin(); it != this->weaponPacks_.end(); ++it)
+        for (std::vector<WeaponPack*>::const_iterator it = this->weaponPacks_.begin(); it != this->weaponPacks_.end(); ++it)
         {
             ++i;
@@ -258,5 +260,5 @@
 
         // Check if the WeaponPack belongs to this WeaponSystem
-        std::set<WeaponPack *>::iterator it1 = this->weaponPacks_.find(wPack);
+        std::vector<WeaponPack *>::iterator it1 = std::find( this->weaponPacks_.begin(), this->weaponPacks_.end(), wPack );
         if (it1 == this->weaponPacks_.end())
             return;
Index: code/branches/pickup2/src/orxonox/weaponsystem/WeaponSystem.h
===================================================================
--- code/branches/pickup2/src/orxonox/weaponsystem/WeaponSystem.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/weaponsystem/WeaponSystem.h	(revision 6412)
@@ -92,5 +92,5 @@
             std::map<unsigned int, WeaponSet *> weaponSets_;
             std::vector<WeaponSlot *> weaponSlots_;
-            std::set<WeaponPack *> weaponPacks_;
+            std::vector<WeaponPack *> weaponPacks_;
             std::map<Identifier *, Munition *> munitions_;
             Pawn * pawn_;
Index: code/branches/pickup2/src/orxonox/worldentities/CMakeLists.txt
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/CMakeLists.txt	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/CMakeLists.txt	(revision 6412)
@@ -7,4 +7,5 @@
 
   BigExplosion.cc
+  EffectContainer.cc
   ExplosionChunk.cc
   CameraPosition.cc
Index: code/branches/pickup2/src/orxonox/worldentities/ControllableEntity.cc
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/ControllableEntity.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/ControllableEntity.cc	(revision 6412)
@@ -36,4 +36,5 @@
 #include "core/GameMode.h"
 #include "core/XMLPort.h"
+#include "network/NetworkFunction.h"
 
 #include "Scene.h"
@@ -47,4 +48,7 @@
 {
     CreateFactory(ControllableEntity);
+
+    registerMemberNetworkFunction( ControllableEntity, fire );
+    registerMemberNetworkFunction( ControllableEntity, setTargetInternal );
 
     ControllableEntity::ControllableEntity(BaseObject* creator) : MobileEntity(creator)
@@ -62,7 +66,9 @@
         this->camera_ = 0;
         this->xmlcontroller_ = 0;
+        this->controller_ = 0;
         this->reverseCamera_ = 0;
         this->bDestroyWhenPlayerLeft_ = false;
         this->cameraPositionRootNode_ = this->node_->createChildSceneNode();
+        this->currentCameraPosition_ = 0;
         this->bMouseLook_ = false;
         this->mouseLookSpeed_ = 200;
@@ -169,4 +175,5 @@
             {
                 this->cameraPositions_.front()->attachCamera(this->camera_);
+                this->currentCameraPosition_ = this->cameraPositions_.front().get();
             }
             else if (this->cameraPositions_.size() > 0)
@@ -178,7 +185,13 @@
                         ++it;
                         if (it != this->cameraPositions_.end())
+                        {
                             (*it)->attachCamera(this->camera_);
+                            this->currentCameraPosition_ = *it;
+                        }
                         else
+                        {
                             (*this->cameraPositions_.begin())->attachCamera(this->camera_);
+                            this->currentCameraPosition_ = *this->cameraPositions_.begin();
+                        }
                         break;
                     }
@@ -188,4 +201,5 @@
             {
                 this->camera_->attachToNode(this->cameraPositionRootNode_);
+                this->currentCameraPosition_ = 0;
             }
         }
@@ -198,4 +212,11 @@
         if (!this->bMouseLook_)
             this->cameraPositionRootNode_->setOrientation(Quaternion::IDENTITY);
+        if (this->getCamera())
+        {
+            if (!this->bMouseLook_&& this->currentCameraPosition_->getDrag())
+                this->getCamera()->setDrag(true);
+            else
+                this->getCamera()->setDrag(false);
+        }
     }
 
@@ -216,4 +237,37 @@
         if (this->bMouseLook_)
             this->cameraPositionRootNode_->roll(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
+    }
+
+    void ControllableEntity::fire(unsigned int firemode)
+    {
+        if(GameMode::isMaster())
+        {
+            this->fired(firemode);
+        }
+        else
+        {
+            callMemberNetworkFunction(ControllableEntity, fire, this->getObjectID(), 0, firemode);
+        }
+    }
+
+    void ControllableEntity::setTarget( WorldEntity* target )
+    {
+        this->target_ = target;
+        if ( !GameMode::isMaster() )
+        {
+            if ( target != 0 )
+            {
+                callMemberNetworkFunction(ControllableEntity, setTargetInternal, this->getObjectID(), 0, target->getObjectID() );
+            }
+           else
+           {
+                callMemberNetworkFunction(ControllableEntity, setTargetInternal, this->getObjectID(), 0, OBJECTID_UNKNOWN );
+           }
+        }
+    }
+
+    void ControllableEntity::setTargetInternal( uint32_t targetID )
+    {
+        this->setTarget( orxonox_cast<WorldEntity*>(Synchronisable::getSynchronisable(targetID)) );
     }
 
@@ -279,15 +333,21 @@
             this->camera_ = new Camera(this);
             this->camera_->requestFocus();
-            if (this->cameraPositionTemplate_ != "")
+            if (!this->cameraPositionTemplate_.empty())
                 this->addTemplate(this->cameraPositionTemplate_);
             if (this->cameraPositions_.size() > 0)
+            {
                 this->cameraPositions_.front()->attachCamera(this->camera_);
+                this->currentCameraPosition_ = this->cameraPositions_.front();
+            }
             else
+            {
                 this->camera_->attachToNode(this->cameraPositionRootNode_);
+                this->currentCameraPosition_ = 0;
+            }
         }
 
         if (!this->hud_ && GameMode::showsGraphics())
         {
-            if (this->hudtemplate_ != "")
+            if (!this->hudtemplate_.empty())
             {
                 this->hud_ = new OverlayGroup(this);
Index: code/branches/pickup2/src/orxonox/worldentities/ControllableEntity.h
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/ControllableEntity.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/ControllableEntity.h	(revision 6412)
@@ -84,5 +84,6 @@
                 { this->rotateRoll(Vector2(value, 0)); }
 
-            virtual void fire(unsigned int firemode) {}
+            void fire(unsigned int firemode);
+            virtual void fired(unsigned int firemode) {}
             virtual void reload() {}
 
@@ -139,4 +140,14 @@
             inline Controller* getXMLController() const
                 { return this->xmlcontroller_; }
+
+            inline Controller* getController() const
+                { return this->controller_; }
+            inline void setController(Controller* val)
+                { this->controller_ = val; }
+
+            virtual void setTarget( WorldEntity* target );
+            virtual WorldEntity* getTarget()
+                { return this->target_.get(); }
+            void setTargetInternal( uint32_t targetID );
 
         protected:
@@ -199,7 +210,10 @@
             Ogre::SceneNode* cameraPositionRootNode_;
             std::list<SmartPtr<CameraPosition> > cameraPositions_;
+            CameraPosition* currentCameraPosition_;
             std::string cameraPositionTemplate_;
             Controller* xmlcontroller_;
+            Controller* controller_;
             CameraPosition* reverseCamera_;
+            WeakPtr<WorldEntity> target_;
     };
 }
Index: code/branches/pickup2/src/orxonox/worldentities/EffectContainer.cc
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/EffectContainer.cc	(revision 6412)
+++ code/branches/pickup2/src/orxonox/worldentities/EffectContainer.cc	(revision 6412)
@@ -0,0 +1,111 @@
+/*
+ *   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:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "EffectContainer.h"
+
+extern "C" {
+#include <lua.h>
+}
+
+#include "core/CoreIncludes.h"
+#include "core/LuaState.h"
+#include "core/XMLPort.h"
+#include "worldentities/WorldEntity.h"
+
+namespace orxonox
+{
+    CreateFactory(EffectContainer);
+
+    EffectContainer::EffectContainer(BaseObject* creator)
+        : BaseObject(creator)
+        , lua_(NULL)
+    {
+        RegisterObject(EffectContainer);
+    }
+
+    EffectContainer::~EffectContainer()
+    {
+    }
+
+    void EffectContainer::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EffectContainer, XMLPort, xmlelement, mode);
+        XMLPortParam(EffectContainer, "condition", setCondition, getCondition, xmlelement, mode);
+        XMLPortObject(EffectContainer, WorldEntity, "", addEffect, getEffect, xmlelement, mode);
+    }
+
+    void EffectContainer::setCondition(const std::string& condition)
+    {
+        // TODO: Watch out for code injection!
+        this->condition_ = condition;
+        if (this->lua_)
+        {
+            this->lua_->doString(
+                this->functionName_ + " = function() \n"
+                "    return (" + condition + ") \n"
+                "end"
+            );
+        }
+    }
+
+    void EffectContainer::setLuaState(LuaState* state, const std::string& functionName)
+    {
+        this->functionName_ = functionName;
+        this->lua_ = state;
+        this->setCondition(this->condition_);
+    }
+
+    void EffectContainer::addEffect(WorldEntity* effect)
+    {
+        this->effects_.push_back(effect);
+    }
+
+    WorldEntity* EffectContainer::getEffect(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::vector<WorldEntity*>::const_iterator it = this->effects_.begin(); it != this->effects_.end(); ++it)
+            if (i == index)
+                return (*it);
+        return NULL;
+    }
+
+    void EffectContainer::updateCondition()
+    {
+        if (this->lua_)
+        {
+            lua_getglobal(this->lua_->getInternalLuaState(), this->functionName_.c_str());
+            lua_call(this->lua_->getInternalLuaState(), 0, 1);
+            bool result = (bool)lua_toboolean(this->lua_->getInternalLuaState(), -1);
+            lua_pop(this->lua_->getInternalLuaState(), 1);
+            for (std::vector<WorldEntity*>::const_iterator it = this->effects_.begin(); it != this->effects_.end(); ++it)
+            {
+                (*it)->setMainState(result);
+            }
+        }
+    }
+}
Index: code/branches/pickup2/src/orxonox/worldentities/EffectContainer.h
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/EffectContainer.h	(revision 6412)
+++ code/branches/pickup2/src/orxonox/worldentities/EffectContainer.h	(revision 6412)
@@ -0,0 +1,71 @@
+/*
+ *   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:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EffectContainer_H__
+#define _EffectContainer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <vector>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport EffectContainer : public BaseObject
+    {
+        public:
+            EffectContainer(BaseObject* creator);
+            virtual ~EffectContainer();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void setLuaState(LuaState* state, const std::string& functionName);
+
+            void setCondition(const std::string& condition);
+            inline const std::string& getCondition() const
+                { return this->condition_; }
+
+            void addEffect(WorldEntity* effect);
+            WorldEntity* getEffect(unsigned int index) const;
+
+            inline std::vector<WorldEntity*>::const_iterator getEffectsBegin()
+                { return this->effects_.begin(); }
+            inline std::vector<WorldEntity*>::const_iterator getEffectsEnd()
+                { return this->effects_.end(); }
+
+            void updateCondition();
+
+        private:
+            std::string               condition_;
+            std::string               functionName_;
+            LuaState*                 lua_;
+            std::vector<WorldEntity*> effects_;
+    };
+}
+
+#endif /* _EffectContainer_H__ */
Index: code/branches/pickup2/src/orxonox/worldentities/MovableEntity.cc
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/MovableEntity.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/MovableEntity.cc	(revision 6412)
@@ -79,5 +79,6 @@
             if (victim)
             {
-                victim->damage(this->collisionDamage_ * (victim->getVelocity() - this->getVelocity()).length());
+                float damage = this->collisionDamage_ * (victim->getVelocity() - this->getVelocity()).length();
+                victim->hit(0, contactPoint, damage);
             }
         }
Index: code/branches/pickup2/src/orxonox/worldentities/MovableEntity.h
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/MovableEntity.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/MovableEntity.h	(revision 6412)
@@ -70,8 +70,8 @@
 
             inline void setEnableCollisionDamage(bool c)
-            { 
-                this->enableCollisionDamage_ = c; 
+            {
+                this->enableCollisionDamage_ = c;
                 this->enableCollisionCallback();
-            } 
+            }
 
             inline bool getEnableCollisionDamage()
Index: code/branches/pickup2/src/orxonox/worldentities/StaticEntity.cc
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/StaticEntity.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/StaticEntity.cc	(revision 6412)
@@ -42,5 +42,5 @@
     {
         RegisterObject(StaticEntity);
-        
+
         this->setPriority(Priority::VeryLow);
 
Index: code/branches/pickup2/src/orxonox/worldentities/WorldEntity.cc
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/WorldEntity.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/WorldEntity.cc	(revision 6412)
@@ -472,25 +472,33 @@
     //! Attaches an Ogre::MovableObject to this WorldEntity.
     void WorldEntity::attachOgreObject(Ogre::MovableObject* object)
-        { this->node_->attachObject(object); }
+    {
+        this->node_->attachObject(object);
+        object->setUserObject(this);
+    }
+
     void WorldEntity::attachOgreObject(Ogre::BillboardSet* object)
-        { this->node_->attachObject(object); }
+        { this->attachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
     void WorldEntity::attachOgreObject(Ogre::Camera* object)
-        { this->node_->attachObject(object); }
+        { this->attachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
     void WorldEntity::attachOgreObject(Ogre::Entity* object)
-        { this->node_->attachObject(object); }
+        { this->attachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
     void WorldEntity::attachOgreObject(Ogre::ParticleSystem* object)
-        { this->node_->attachObject(object); }
+        { this->attachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
 
     //! Detaches an Ogre::MovableObject from this WorldEntity.
     void WorldEntity::detachOgreObject(Ogre::MovableObject* object)
-        { this->node_->detachObject(object); }
+    {
+        object->setUserObject(NULL);
+        this->node_->detachObject(object);
+    }
+
     void WorldEntity::detachOgreObject(Ogre::BillboardSet* object)
-        { this->node_->detachObject(object); }
+        { this->detachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
     void WorldEntity::detachOgreObject(Ogre::Camera* object)
-        { this->node_->detachObject(object); }
+        { this->detachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
     void WorldEntity::detachOgreObject(Ogre::Entity* object)
-        { this->node_->detachObject(object); }
+        { this->detachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
     void WorldEntity::detachOgreObject(Ogre::ParticleSystem* object)
-        { this->node_->detachObject(object); }
+        { this->detachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
 
     //! Detaches an Ogre::MovableObject (by string) from this WorldEntity.
@@ -646,5 +654,5 @@
     /**
     @brief
-        Makes this WorldEntity look a specific target location.
+        Makes this WorldEntity look at a specific target location.
     @param relativeTo
         @see WorldEntity::TransformSpace
@@ -806,5 +814,5 @@
     void WorldEntity::setCollisionTypeStr(const std::string& typeStr)
     {
-        std::string typeStrLower = getLowercase(typeStr);
+        const std::string& typeStrLower = getLowercase(typeStr);
         CollisionType type;
         if (typeStrLower == "dynamic")
@@ -913,5 +921,5 @@
     }
 
-    //! Copies our own parameters for restitution, angular factor, dampings and friction to the bullet rigid body.
+    //! Copies our own parameters for restitution, angular factor, damping and friction to the bullet rigid body.
     void WorldEntity::internalSetPhysicsProps()
     {
Index: code/branches/pickup2/src/orxonox/worldentities/WorldEntity.h
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/WorldEntity.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/WorldEntity.h	(revision 6412)
@@ -33,4 +33,5 @@
 #include "OrxonoxPrereqs.h"
 
+#include <OgreUserDefinedObject.h>
 #ifdef ORXONOX_RELEASE
 #  include <OgreSceneNode.h>
@@ -55,5 +56,5 @@
 
         The basic task of the WorldEntity is provide a location, a direction and a scaling and the possibility
-        to create an entire hierarchy of derivated objects.
+        to create an entire hierarchy of derived objects.
         It is also the basis for the physics interface to the Bullet physics engine.
         Every WorldEntity can have a specific collision type: @see CollisionType
@@ -63,11 +64,11 @@
         There is also support for attaching WorldEntities with physics to each other. Currently, the collision shape
         of both objects simply get merged into one larger shape (for static collision type).
-        The phyiscal body that is internally stored and administrated has the following supported properties:
-        - Restitution, angular factor, linear damping, angular damping, fricition, mass and collision shape.
+        The physical body that is internally stored and administrated has the following supported properties:
+        - Restitution, angular factor, linear damping, angular damping, friction, mass and collision shape.
         You can get more information at the corresponding set function.
 
         Collision shapes: These are controlled by the internal WorldEntityCollisionShape. @see WorldEntityCollisionShape.
     */
-    class _OrxonoxExport WorldEntity : public BaseObject, public Synchronisable, public btMotionState
+    class _OrxonoxExport WorldEntity : public BaseObject, public Synchronisable, public btMotionState, public Ogre::UserDefinedObject
     {
         friend class Scene;
@@ -318,5 +319,5 @@
                 Sets an artificial parameter that tells how much torque is applied when you apply a non-central force.
 
-                Normally the angular factor is 1, which means it's physically 'correct'. Howerver if you have a player
+                Normally the angular factor is 1, which means it's physically 'correct'. However if you have a player
                 character that should not rotate when hit sideways, you can set the angular factor to 0.
             */
@@ -394,5 +395,5 @@
                 You can override this function in a derived class to constrain the collision to e.g. None or Dynamic.
                 A projectile may not prove very useful if there is no physical body. Simply set the CollisionType
-                in its constructor and override this method. But be careful that a derived classe's virtual functions
+                in its constructor and override this method. But be careful that a derived class's virtual functions
                 don't yet exist in the constructor if a base class.
             */
Index: code/branches/pickup2/src/orxonox/worldentities/pawns/Pawn.cc
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/pawns/Pawn.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/pawns/Pawn.cc	(revision 6412)
@@ -38,4 +38,5 @@
 #include "PawnManager.h"
 #include "infos/PlayerInfo.h"
+#include "controllers/Controller.h"
 #include "gametypes/Gametype.h"
 #include "graphics/ParticleSpawner.h"
@@ -52,6 +53,4 @@
     CreateFactory(Pawn);
 
-    registerMemberNetworkFunction( Pawn, doFire );
-
     Pawn::Pawn(BaseObject* creator) : ControllableEntity(creator)
     {
@@ -69,4 +68,6 @@
 
         this->spawnparticleduration_ = 3.0f;
+
+        this->aimPosition_ = Vector3::ZERO;
 
         //TODO: Remove.
@@ -111,5 +112,5 @@
         XMLPortObject(Pawn, WeaponSlot, "weaponslots", addWeaponSlot, getWeaponSlot, xmlelement, mode);
         XMLPortObject(Pawn, WeaponSet, "weaponsets", addWeaponSet, getWeaponSet, xmlelement, mode);
-        XMLPortObject(Pawn, WeaponPack, "weapons", addWeaponPack, getWeaponPack, xmlelement, mode);
+        XMLPortObject(Pawn, WeaponPack, "weapons", addWeaponPackXML, getWeaponPack, xmlelement, mode);
     }
 
@@ -120,4 +121,5 @@
         registerVariable(this->initialHealth_, VariableDirection::ToClient);
         registerVariable(this->bReload_,       VariableDirection::ToServer);
+        registerVariable(this->aimPosition_,   Bidirectionality::ServerMaster, 0, true);
     }
 
@@ -167,5 +169,5 @@
     void Pawn::hit(Pawn* originator, const Vector3& force, float damage)
     {
-        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator))
+        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
         {
             this->damage(damage, originator);
@@ -176,4 +178,17 @@
     }
 
+    void Pawn::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
+    {
+        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
+        {
+            this->damage(damage, originator);
+
+            if ( this->getController() )
+                this->getController()->hit(originator, contactpoint, damage);
+
+            // play hit effect
+        }
+    }
+
     void Pawn::kill()
     {
@@ -185,5 +200,5 @@
     {
         // play spawn effect
-        if (this->spawnparticlesource_ != "")
+        if (!this->spawnparticlesource_.empty())
         {
             ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
@@ -264,22 +279,8 @@
     }
 
-    void Pawn::fire(unsigned int firemode)
-    {
-        this->doFire(firemode);
-    }
-
-    void Pawn::doFire(uint8_t firemode)
-    {
-        if(GameMode::isMaster())
-        {
-            if (this->weaponSystem_)
-                this->weaponSystem_->fire(firemode);
-        }
-        else
-        {
-            callMemberNetworkFunction(Pawn, doFire, this->getObjectID(), 0, firemode);
-            if (this->weaponSystem_)
-                this->weaponSystem_->fire(firemode);
-        }
+    void Pawn::fired(unsigned int firemode)
+    {
+        if (this->weaponSystem_)
+            this->weaponSystem_->fire(firemode);
     }
 
@@ -343,4 +344,11 @@
     }
 
+    void Pawn::addWeaponPackXML(WeaponPack * wPack)
+    {
+        if (this->weaponSystem_)
+            if (!this->weaponSystem_->addWeaponPack(wPack))
+                wPack->destroy();
+    }
+
     WeaponPack * Pawn::getWeaponPack(unsigned int index) const
     {
Index: code/branches/pickup2/src/orxonox/worldentities/pawns/Pawn.h
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/pawns/Pawn.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/pawns/Pawn.h	(revision 6412)
@@ -76,11 +76,10 @@
                 { return this->lastHitOriginator_; }
 
-            virtual void damage(float damage, Pawn* originator = 0);
             virtual void hit(Pawn* originator, const Vector3& force, float damage);
+            virtual void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage);
             virtual void kill();
 
-            virtual void fire(unsigned int firemode);
+            virtual void fired(unsigned int firemode);
             virtual void reload();
-            virtual void doFire(uint8_t firemode);
             virtual void postSpawn();
 
@@ -90,4 +89,5 @@
             WeaponSet * getWeaponSet(unsigned int index) const;
             void addWeaponPack(WeaponPack * wPack);
+            void addWeaponPackXML(WeaponPack * wPack);
             WeaponPack * getWeaponPack(unsigned int index) const;
 
@@ -119,4 +119,9 @@
             virtual void startLocalHumanControl();
 
+            void setAimPosition( Vector3 position )
+                { this->aimPosition_ = position; }
+            Vector3 getAimPosition()
+                { return this->aimPosition_; }
+
         protected:
             virtual void setPlayer(PlayerInfo* player);
@@ -127,4 +132,6 @@
             virtual void deatheffect();
             virtual void spawneffect();
+
+            virtual void damage(float damage, Pawn* originator = 0);
 
             bool bAlive_;
@@ -149,4 +156,6 @@
             inline void setWeaponSystem(WeaponSystem* weaponsystem)
                 { this->weaponSystem_ = weaponsystem; }
+
+            Vector3 aimPosition_;
     };
 }
Index: code/branches/pickup2/src/orxonox/worldentities/pawns/SpaceShip.cc
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/pawns/SpaceShip.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/pawns/SpaceShip.cc	(revision 6412)
@@ -187,5 +187,5 @@
     void SpaceShip::loadEngineTemplate()
     {
-        if (this->enginetemplate_ != "")
+        if (!this->enginetemplate_.empty())
         {
             Template* temp = Template::getTemplate(this->enginetemplate_);
Index: code/branches/pickup2/src/orxonox/worldentities/pawns/Spectator.cc
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/pawns/Spectator.cc	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/pawns/Spectator.cc	(revision 6412)
@@ -189,5 +189,5 @@
     }
 
-    void Spectator::fire(unsigned int firemode)
+    void Spectator::fired(unsigned int firemode)
     {
         if (this->getPlayer())
Index: code/branches/pickup2/src/orxonox/worldentities/pawns/Spectator.h
===================================================================
--- code/branches/pickup2/src/orxonox/worldentities/pawns/Spectator.h	(revision 6405)
+++ code/branches/pickup2/src/orxonox/worldentities/pawns/Spectator.h	(revision 6412)
@@ -55,5 +55,5 @@
             virtual void rotateRoll(const Vector2& value);
 
-            virtual void fire(unsigned int firemode);
+            virtual void fired(unsigned int firemode);
             virtual void greet();
 
