Index: code/trunk/src/libraries/tools/ResourceLocation.cc
===================================================================
--- code/trunk/src/libraries/tools/ResourceLocation.cc	(revision 7851)
+++ code/trunk/src/libraries/tools/ResourceLocation.cc	(revision 8079)
@@ -30,4 +30,5 @@
 
 #include <OgreResourceGroupManager.h>
+#include <OgreException.h>
 #include <boost/filesystem.hpp>
 
Index: code/trunk/src/libraries/tools/Shader.cc
===================================================================
--- code/trunk/src/libraries/tools/Shader.cc	(revision 7851)
+++ code/trunk/src/libraries/tools/Shader.cc	(revision 8079)
@@ -30,12 +30,6 @@
 
 #include <OgreCompositorManager.h>
-#include <OgreCompositorInstance.h>
-#include <OgreSceneManager.h>
 #include <OgreRoot.h>
 #include <OgrePlugin.h>
-#include <OgreMaterial.h>
-#include <OgreTechnique.h>
-#include <OgrePass.h>
-#include <OgreMaterialManager.h>
 
 #include "core/CoreIncludes.h"
@@ -45,7 +39,7 @@
 namespace orxonox
 {
-    bool Shader::bLoadedCgPlugin_s = false;
-    Shader::MaterialMap Shader::parameters_s;
-
+    /**
+        @brief Initializes the values and sets the scene manager.
+    */
     Shader::Shader(Ogre::SceneManager* scenemanager) : compositorInstance_(0)
     {
@@ -53,277 +47,195 @@
 
         this->scenemanager_ = scenemanager;
-        this->compositorInstance_ = 0;
         this->bVisible_ = true;
         this->bLoadCompositor_ = GameMode::showsGraphics();
-        this->bViewportInitialized_ = false;
-
-        if (this->bLoadCompositor_ && Ogre::Root::getSingletonPtr())
-        {
-            Shader::bLoadedCgPlugin_s = false;
+        this->registeredAsListener_ = false;
+
+        static bool hasCgProgramManager = Shader::hasCgProgramManager();
+
+        this->bLoadCompositor_ &= hasCgProgramManager;
+    }
+
+    /**
+        @brief Removes the compositor and frees the resources.
+    */
+    Shader::~Shader()
+    {
+        if (this->compositorInstance_ && GraphicsManager::getInstance().getViewport())
+            Ogre::CompositorManager::getSingleton().removeCompositor(GraphicsManager::getInstance().getViewport(), this->compositorName_);
+    }
+
+    /**
+        @brief Inherited from ViewportEventListener - called if the camera changes.
+
+        Since the new camera could be in a different scene, the shader has to make sure
+        it deactivates or activates itself accordingly.
+
+        Additionally the shader has to be turned off and on even if the camera stays in
+        the same scene to fix a weird behavior of Ogre.
+    */
+    void Shader::cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera)
+    {
+        if (!this->bLoadCompositor_ || !this->scenemanager_)
+            return;
+
+        // load the compositor if not already done
+        if (!this->compositorName_.empty() && !this->compositorInstance_)
+            this->changedCompositorName(viewport);
+
+        // update compositor in viewport (shader should only be active if the current camera is in the same scene as the shader)
+
+        // Note:
+        // The shader needs also to be switched off and on after changing the camera in the
+        // same scene to avoid weird behaviour with active compositors while switching the
+        // camera (like freezing the image)
+        //
+        // Last known Ogre version needing this workaround:
+        // 1.4.8
+        // 1.7.2
+
+        if (oldCamera && this->scenemanager_ == oldCamera->getSceneManager())
+            Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, false);
+
+        if (viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager())
+            Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible());
+    }
+
+    /**
+        @brief Changes the compositor - default viewport.
+    */
+    void Shader::changedCompositorName()
+    {
+        // For the moment, we get the viewport always from the graphics manager
+        // TODO: Try to support multiple viewports - note however that scenemanager_->getCurrentViewport() returns NULL
+        //       after switching to a camera in a different scene (only for the first time this scene is displayed though)
+        this->changedCompositorName(GraphicsManager::getInstance().getViewport());
+    }
+
+    /**
+        @brief Changes the compositor.
+    */
+    void Shader::changedCompositorName(Ogre::Viewport* viewport)
+    {
+        if (this->bLoadCompositor_)
+        {
+            assert(viewport);
+            if (this->compositorInstance_)
+            {
+                // remove the old compositor, remove the listener
+                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositorName_);
+                this->compositorInstance_->removeListener(this);
+                this->compositorInstance_ = 0;
+            }
+            if (!this->compositorName_.empty())
+            {
+                // add the new compositor
+                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositorName_);
+                if (this->compositorInstance_)
+                {
+                    // register as listener if required
+                    if (this->registeredAsListener_)
+                        this->compositorInstance_->addListener(this);
+                    // set visibility according to the isVisible() and the camera/viewport
+                    if (viewport->getCamera())
+                        Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible() && viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager());
+                }
+                else
+                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositorName_ << "\"." << std::endl;
+            }
+            this->oldcompositorName_ = this->compositorName_;
+        }
+    }
+
+    /**
+        @brief Changes the visibility of the shader. Doesn't free any resources if set to invisible.
+    */
+    void Shader::updateVisibility()
+    {
+        if (this->compositorInstance_)
+            Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, this->isVisible());
+    }
+
+    /**
+        @brief Defines a new integer value for a given parameter. The parameter will be updated if the compositor is rendered the next time.
+    */
+    void Shader::setParameter(size_t technique, size_t pass, const std::string& parameter, int value)
+    {
+        ParameterContainer container = {technique, pass, parameter, value, 0.0f, MT_Type::Int};
+        this->parameters_.push_back(container);
+        this->addAsListener();
+    }
+
+    /**
+        @brief Defines a new float value for a given parameter. The parameter will be updated if the compositor is rendered the next time.
+    */
+    void Shader::setParameter(size_t technique, size_t pass, const std::string& parameter, float value)
+    {
+        ParameterContainer container = {technique, pass, parameter, 0, value, MT_Type::Float};
+        this->parameters_.push_back(container);
+        this->addAsListener();
+    }
+
+    /**
+        @brief Registers the shader as CompositorInstance::Listener at the compositor. Used to change parameters.
+    */
+    void Shader::addAsListener()
+    {
+        if (!this->registeredAsListener_)
+        {
+            this->registeredAsListener_ = true;
+            if (this->compositorInstance_)
+                this->compositorInstance_->addListener(this);
+        }
+    }
+
+    /**
+        @brief Inherited by Ogre::CompositorInstance::Listener, called whenever the material is rendered. Used to change parameters.
+    */
+    void Shader::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr)
+    {
+        // iterate through the list of parameters
+        for (std::list<ParameterContainer>::iterator it = this->parameters_.begin(); it != this->parameters_.end(); ++it)
+        {
+            Ogre::Technique* techniquePtr = materialPtr->getTechnique(it->technique_);
+            if (techniquePtr)
+            {
+                Ogre::Pass* passPtr = techniquePtr->getPass(it->pass_);
+                if (passPtr)
+                {
+                    // change the value of the parameter depending on its type
+                    switch (it->valueType_)
+                    {
+                        case MT_Type::Int:
+                            passPtr->getFragmentProgramParameters()->setNamedConstant(it->parameter_, it->valueInt_);
+                            break;
+                        case MT_Type::Float:
+                            passPtr->getFragmentProgramParameters()->setNamedConstant(it->parameter_, it->valueFloat_);
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                else
+                    COUT(2) << "Warning: No pass " << it->pass_ << " in technique " << it->technique_ << " in compositor \"" << this->compositorName_ << "\" or pass has no shader." << std::endl;
+            }
+            else
+                COUT(2) << "Warning: No technique " << it->technique_ << " in compositor \"" << this->compositorName_ << "\" or technique has no pass with shader." << std::endl;
+        }
+        this->parameters_.clear();
+    }
+
+    /**
+        @brief Detects if the Cg program manager plugin is active.
+    */
+    /* static */ bool Shader::hasCgProgramManager()
+    {
+        if (Ogre::Root::getSingletonPtr())
+        {
             const Ogre::Root::PluginInstanceList& plugins = Ogre::Root::getSingleton().getInstalledPlugins();
             for (size_t i = 0; i < plugins.size(); ++i)
-            {
                 if (plugins[i]->getName() == "Cg Program Manager")
-                {
-                    Shader::bLoadedCgPlugin_s = true;
-                    break;
-                }
-            }
-        }
-
-        this->bLoadCompositor_ &= Shader::bLoadedCgPlugin_s;
-    }
-
-    Shader::~Shader()
-    {
-        if (this->compositorInstance_ && this->bLoadCompositor_)
-        {
-            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
-            assert(viewport);
-            Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->compositor_);
-        }
-
-    }
-
-    void Shader::setSceneManager(Ogre::SceneManager* scenemanager)
-    {
-        this->scenemanager_ = scenemanager;
-        this->bViewportInitialized_ = false;
-    }
-
-    void Shader::tick(float dt)
-    {
-        SUPER(Shader, tick, dt);
-
-        if (this->bLoadCompositor_ && !this->bViewportInitialized_ && this->scenemanager_ && this->scenemanager_->getCurrentViewport())
-        {
-            this->bViewportInitialized_ = true;
-            this->updateVisibility();
-        }
-    }
-
-    void Shader::changedCompositor()
-    {
-        if (this->bLoadCompositor_)
-        {
-            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
-            assert(viewport);
-            if (!this->oldcompositor_.empty())
-            {
-                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositor_);
-                this->compositorInstance_ = 0;
-            }
-            if (!this->compositor_.empty())
-            {
-                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositor_);
-                if (!this->compositorInstance_)
-                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositor_ << "\"." << std::endl;
-                Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositor_, this->bViewportInitialized_ && this->isVisible());
-            }
-            this->oldcompositor_ = this->compositor_;
-        }
-    }
-
-    void Shader::updateVisibility()
-    {
-        if (this->compositorInstance_ && this->scenemanager_)
-            this->compositorInstance_->setEnabled(this->scenemanager_->getCurrentViewport() && this->isVisible());
-    }
-
-    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
-    {
-        if (Shader::_setParameter(material, technique, pass, parameter, value))
-        {
-            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
-            {
-                this->compositorInstance_->setEnabled(false);
-                this->compositorInstance_->setEnabled(true);
-            }
-        }
-    }
-
-    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
-    {
-        if (Shader::_setParameter(material, technique, pass, parameter, value))
-        {
-            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
-            {
-                this->compositorInstance_->setEnabled(false);
-                this->compositorInstance_->setEnabled(true);
-            }
-        }
-    }
-
-    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-        {
-            if (pointer->first)
-            {
-                if ((*static_cast<float*>(pointer->second)) != value)
-                {
-                    (*static_cast<float*>(pointer->second)) = value;
                     return true;
-                }
-            }
-            else
-            {
-                if ((*static_cast<int*>(pointer->second)) != static_cast<int>(value))
-                {
-                    (*static_cast<int*>(pointer->second)) = static_cast<int>(value);
-                    return true;
-                }
-            }
         }
         return false;
     }
-
-    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-        {
-            if (pointer->first)
-            {
-                if ((*static_cast<float*>(pointer->second)) != static_cast<float>(value))
-                {
-                    (*static_cast<float*>(pointer->second)) = static_cast<float>(value);
-                    return true;
-                }
-            }
-            else
-            {
-                if ((*static_cast<int*>(pointer->second)) != value)
-                {
-                    (*static_cast<int*>(pointer->second)) = value;
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    float Shader::getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-        {
-            if (pointer->first)
-                return (*static_cast<float*>(pointer->second));
-            else
-                return static_cast<float>(*static_cast<int*>(pointer->second));
-        }
-        else
-            return 0;
-    }
-
-    bool Shader::getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-            return pointer->first;
-        else
-            return false;
-    }
-
-    bool Shader::getParameterIsInt(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-            return (!pointer->first);
-        else
-            return false;
-    }
-
-    Shader::ParameterPointer* Shader::getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        if (!GameMode::showsGraphics() || !Shader::bLoadedCgPlugin_s)
-            return 0;
-
-        MaterialMap::iterator material_iterator = Shader::parameters_s.find(material);
-        if (material_iterator != Shader::parameters_s.end())
-        {
-            TechniqueVector& technique_vector = material_iterator->second;
-            if (technique < technique_vector.size())
-            {
-                PassVector& pass_vector = technique_vector[technique];
-                if (pass < pass_vector.size())
-                {
-                    ParameterMap& parameter_map = pass_vector[pass];
-                    ParameterMap::iterator parameter_iterator = parameter_map.find(parameter);
-
-                    if (parameter_iterator != parameter_map.end())
-                        return (&parameter_iterator->second);
-                    else
-                        COUT(2) << "Warning: No shader parameter \"" << parameter << "\" in pass " << pass << " in technique " << technique << " in material \"" << material << "\"." << std::endl;
-                }
-                else
-                    COUT(2) << "Warning: No pass " << pass << " in technique " << technique << " in material \"" << material << "\" or pass has no shader." << std::endl;
-            }
-            else
-                COUT(2) << "Warning: No technique " << technique << " in material \"" << material << "\" or technique has no pass with shader." << std::endl;
-        }
-        else
-        {
-            bool foundAtLeastOneShaderParameter = false;
-            Ogre::MaterialManager::ResourceMapIterator iterator = Ogre::MaterialManager::getSingleton().getResourceIterator();
-            Ogre::Material* material_pointer = 0;
-
-            while (iterator.hasMoreElements())
-            {
-                Ogre::Resource* resource = iterator.getNext().get();
-                if (resource->getName() == material)
-                    material_pointer = (Ogre::Material*)resource;
-            }
-
-            if (!material_pointer)
-            {
-                COUT(2) << "Warning: No material with name \"" << material << "\" found." << std::endl;
-                return 0;
-            }
-
-            for (unsigned int t = 0; t < material_pointer->getNumTechniques(); ++t)
-            {
-                Ogre::Technique* technique_pointer = material_pointer->getTechnique(t);
-                if (!technique_pointer)
-                    continue;
-
-                for (unsigned int p = 0; p < technique_pointer->getNumPasses(); ++p)
-                {
-                    Ogre::Pass* pass_pointer = technique_pointer->getPass(p);
-                    if (!pass_pointer)
-                        continue;
-
-                    if (!pass_pointer->getFragmentProgramName().empty())
-                    {
-                        Ogre::GpuProgramParameters* parameter_pointer = pass_pointer->getFragmentProgramParameters().get();
-                        if (!parameter_pointer)
-                            continue;
-
-                        const Ogre::GpuConstantDefinitionMap& constant_definitions = parameter_pointer->getConstantDefinitions().map;
-                        for (Ogre::GpuConstantDefinitionMap::const_iterator definition_iterator = constant_definitions.begin(); definition_iterator != constant_definitions.end(); ++definition_iterator)
-                        {
-                            void* temp = (definition_iterator->second.isFloat())
-                                            ? static_cast<void*>(parameter_pointer->getFloatPointer(definition_iterator->second.physicalIndex))
-                                            : static_cast<void*>(parameter_pointer->getIntPointer(definition_iterator->second.physicalIndex));
-                            ParameterPointer parameter_pointer = ParameterPointer(definition_iterator->second.isFloat(), temp);
-
-                            TechniqueVector& technique_vector = Shader::parameters_s[material];
-                            technique_vector.resize(technique + 1);
-                            PassVector& pass_vector = technique_vector[technique];
-                            pass_vector.resize(pass + 1);
-                            pass_vector[pass][definition_iterator->first] = parameter_pointer;
-                            foundAtLeastOneShaderParameter = true;
-                        }
-                    }
-                }
-            }
-
-            // recursive call if the material was added to the map
-            if (foundAtLeastOneShaderParameter)
-                return Shader::getParameterPointer(material, technique, pass, parameter);
-        }
-        return 0;
-    }
 }
Index: code/trunk/src/libraries/tools/Shader.h
===================================================================
--- code/trunk/src/libraries/tools/Shader.h	(revision 7851)
+++ code/trunk/src/libraries/tools/Shader.h	(revision 8079)
@@ -36,23 +36,23 @@
 #include <vector>
 
+#include <OgreCompositorInstance.h>
+
+#include "util/MultiType.h"
 #include "util/OgreForwardRefs.h"
-#include "tools/interfaces/Tickable.h"
+#include "core/ViewportEventListener.h"
 
 namespace orxonox
 {
-    class _ToolsExport Shader : public Tickable
+    /**
+        @brief Shader is a wrapper class around Ogre::CompositorInstance. It provides some
+        functions to easily change the visibility and parameters for shader programs.
+    */
+    class _ToolsExport Shader : public ViewportEventListener, public Ogre::CompositorInstance::Listener
     {
-        typedef std::pair<bool, void*>                  ParameterPointer;
-        typedef std::map<std::string, ParameterPointer> ParameterMap;
-        typedef std::vector<ParameterMap>               PassVector;
-        typedef std::vector<PassVector>                 TechniqueVector;
-        typedef std::map<std::string, TechniqueVector>  MaterialMap;
-
         public:
             Shader(Ogre::SceneManager* scenemanager = 0);
             virtual ~Shader();
 
-            virtual void tick(float dt);
-
+            /// Defines if the shader is visible or not.
             inline void setVisible(bool bVisible)
             {
@@ -63,45 +63,66 @@
                 }
             }
+            /// Returns whether or not the shader is visible.
             inline bool isVisible() const
                 { return this->bVisible_; }
             void updateVisibility();
 
-            inline void setCompositor(const std::string& compositor)
+            /// Defines the compositor's name (located in a .compositor file).
+            inline void setCompositorName(const std::string& name)
             {
-                if (this->compositor_ != compositor)
+                if (this->compositorName_ != name)
                 {
-                    this->compositor_ = compositor;
-                    this->changedCompositor();
+                    this->compositorName_ = name;
+                    this->changedCompositorName();
                 }
             }
-            inline const std::string& getCompositor() const
-                { return this->compositor_; }
-            void changedCompositor();
+            /// Returns the compositor's name.
+            inline const std::string& getCompositorName() const
+                { return this->compositorName_; }
+            void changedCompositorName();
+            void changedCompositorName(Ogre::Viewport* viewport);
 
-            void setSceneManager(Ogre::SceneManager* scenemanager);
+            /// Sets the scenemanager (usually provided in the constructor, but can be set later). Shouldn't be changed once it's set.
+            inline void setSceneManager(Ogre::SceneManager* scenemanager)
+                { this->scenemanager_ = scenemanager; }
+            /// Returns the scene manager.
             inline Ogre::SceneManager* getSceneManager() const
                 { return this->scenemanager_; }
 
-            void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
-            void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
+            virtual void cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera);
 
-            static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
-            static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
-            static float getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
-            static bool  getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
-            static bool  getParameterIsInt  (const std::string& material, size_t technique, size_t pass, const std::string& parameter);
-            static ParameterPointer* getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+            void setParameter(size_t technique, size_t pass, const std::string& parameter, float value);
+            void setParameter(size_t technique, size_t pass, const std::string& parameter, int value);
+
+            virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr);
 
         private:
-            Ogre::SceneManager* scenemanager_;
-            Ogre::CompositorInstance* compositorInstance_;
-            bool bVisible_;
-            bool bLoadCompositor_;
-            bool bViewportInitialized_;
-            std::string compositor_;
-            std::string oldcompositor_;
+            static bool hasCgProgramManager();
 
-            static MaterialMap parameters_s;
-            static bool bLoadedCgPlugin_s;
+            Ogre::SceneManager* scenemanager_;              ///< The scenemanager for which the shader is active
+            Ogre::CompositorInstance* compositorInstance_;  ///< The compositor instance representing the wrapped compositor
+            bool bVisible_;                                 ///< True if the shader should be visible
+            bool bLoadCompositor_;                          ///< True if the compositor should be loaded (usually false if no graphics)
+            std::string compositorName_;                    ///< The name of the current compositor
+            std::string oldcompositorName_;                 ///< The name of the previous compositor (used to unregister)
+
+        private:
+            void addAsListener();
+
+            /// Helper struct to store parameters for shader programs.
+            struct ParameterContainer
+            {
+                size_t technique_;          ///< The ID of the technique
+                size_t pass_;               ///< The ID of the pass
+                std::string parameter_;     ///< The name of the parameter
+
+                int valueInt_;              ///< The desired int value of the parameter
+                float valueFloat_;          ///< The desired float value of the parameter
+
+                MT_Type::Value valueType_;  ///< The type of the parameter (currently only int or float)
+            };
+
+            std::list<ParameterContainer> parameters_;  ///< The list of parameters that should be set on the next update
+            bool registeredAsListener_;                 ///< True if the shader should register itself as listener at the compositor
     };
 }
Index: code/trunk/src/libraries/tools/Timer.cc
===================================================================
--- code/trunk/src/libraries/tools/Timer.cc	(revision 7851)
+++ code/trunk/src/libraries/tools/Timer.cc	(revision 8079)
@@ -35,4 +35,6 @@
 
 #include <set>
+
+#include <boost/bimap.hpp>
 
 #include "util/Clock.h"
@@ -41,25 +43,54 @@
 #include "core/command/CommandExecutor.h"
 #include "core/command/Functor.h"
+#include "tools/interfaces/TimeFactorListener.h"
 
 namespace orxonox
 {
     SetConsoleCommand("delay", &delay).argumentCompleter(1, autocompletion::command());
+    SetConsoleCommand("delayreal", &delayreal).argumentCompleter(1, autocompletion::command());
+    SetConsoleCommand("killdelay", &killdelay);
     SetConsoleCommand("killdelays", &killdelays);
 
-    static std::set<Timer*> delaytimerset;
-
-    /**
-        @brief Console-command: Calls another console command after @a delay seconds.
+    static boost::bimap<unsigned int, Timer*> delaytimers;
+    static unsigned int delayHandleCounter = 0;
+
+    /**
+        @brief Console-command: Calls another console command after @a delay seconds (game time).
         @param delay The delay in seconds
         @param command The console command
-    */
-    void delay(float delay, const std::string& command)
-    {
-        Timer* delaytimer = new Timer();
-        delaytimerset.insert(delaytimer);
+        @return The handle of the delayed command, can be used as argument for killdelay()
+    */
+    unsigned int delay(float delay, const std::string& command)
+    {
+        return addDelayedCommand(new Timer(), delay, command);
+    }
+
+    /**
+        @brief Console-command: Calls another console command after @a delay seconds (real time)
+        @param delay The delay in seconds
+        @param command The console command
+        @return The handle of the delayed command, can be used as argument for killdelay()
+    */
+    unsigned int delayreal(float delay, const std::string& command)
+    {
+        return addDelayedCommand(new RealTimer(), delay, command);
+    }
+
+    /**
+        @brief Helper function, used by delay() and delayreal() to add a delayed command.
+        @param timer The timer which will execute the command
+        @param delay The delay in seconds
+        @param command The console command
+        @return The handle of the delayed command, can be used as argument for killdelay()
+    */
+    unsigned int addDelayedCommand(Timer* timer, float delay, const std::string& command)
+    {
+        delaytimers.insert(boost::bimap<unsigned int, Timer*>::value_type(++delayHandleCounter, timer));
 
         const ExecutorStaticPtr& delayexecutor = createExecutor(createFunctor(&executeDelayedCommand));
-        delayexecutor->setDefaultValues(delaytimer, command);
-        delaytimer->setTimer(delay, false, delayexecutor);
+        delayexecutor->setDefaultValues(timer, command);
+        timer->setTimer(delay, false, delayexecutor);
+
+        return delayHandleCounter;
     }
 
@@ -73,5 +104,5 @@
         CommandExecutor::execute(command);
         timer->destroy();
-        delaytimerset.erase(timer);
+        delaytimers.right.erase(timer);
     }
 
@@ -81,8 +112,21 @@
     void killdelays()
     {
-        for (std::set<Timer*>::iterator it = delaytimerset.begin(); it != delaytimerset.end(); ++it)
-            (*it)->destroy();
-
-        delaytimerset.clear();
+        for (boost::bimap<unsigned int, Timer*>::left_map::iterator it = delaytimers.left.begin(); it != delaytimers.left.end(); ++it)
+            it->second->destroy();
+
+        delaytimers.clear();
+    }
+
+    /**
+        @brief Console-command: Kills a delayed command with given handle.
+    */
+    void killdelay(unsigned int handle)
+    {
+        boost::bimap<unsigned int, Timer*>::left_map::iterator it = delaytimers.left.find(handle);
+        if (it != delaytimers.left.end())
+        {
+            it->second->destroy();
+            delaytimers.left.erase(it);
+        }
     }
 
@@ -93,5 +137,5 @@
     {
         this->init();
-        RegisterObject(Timer);
+        RegisterRootObject(Timer);
     }
 
@@ -106,5 +150,5 @@
     {
         this->init();
-        RegisterObject(Timer);
+        RegisterRootObject(Timer);
 
         this->setTimer(interval, bLoop, executor, bKillAfterCall);
@@ -123,4 +167,12 @@
 
         this->time_ = 0;
+    }
+
+    /**
+        @brief Returns the current time factor of the game.
+    */
+    float Timer::getTimeFactor()
+    {
+        return TimeFactorListener::getTimeFactor();
     }
 
@@ -168,3 +220,24 @@
         }
     }
+
+    ///////////////
+    // RealTimer //
+    ///////////////
+    /// @copydoc Timer::Timer
+    RealTimer::RealTimer()
+    {
+        RegisterObject(RealTimer);
+    }
+
+    /// @copydoc Timer::Timer(float, bool, const ExecutorPtr&, bool)
+    RealTimer::RealTimer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall) : Timer(interval, bLoop, executor, bKillAfterCall)
+    {
+        RegisterObject(RealTimer);
+    }
+
+    /// Returns always 1 because RealTimer doesn't depend on the game time.
+    float RealTimer::getTimeFactor()
+    {
+        return 1;
+    }
 }
Index: code/trunk/src/libraries/tools/Timer.h
===================================================================
--- code/trunk/src/libraries/tools/Timer.h	(revision 7851)
+++ code/trunk/src/libraries/tools/Timer.h	(revision 8079)
@@ -81,18 +81,26 @@
 #include "core/OrxonoxClass.h"
 #include "core/command/Executor.h"
-#include "tools/interfaces/TimeFactorListener.h"
 
 namespace orxonox
 {
-    void delay(float delay, const std::string& command);
-    void killdelays();
+    unsigned int delay(float delay, const std::string& command);
+    unsigned int delayreal(float delay, const std::string& command);
+
+    unsigned int addDelayedCommand(Timer* timer, float delay, const std::string& command);
     void executeDelayedCommand(Timer* timer, const std::string& command);
 
+    void killdelay(unsigned int handle);
+    void killdelays();
+
     /**
-        @brief Timer is a helper class that executes a function after a given amount of time.
+        @brief Timer is a helper class that executes a function after a given amount of seconds in game-time.
 
         @see See @ref TimerExample "Timer.h" for an example.
+
+        The time interval of Timer depends on the game time, hence it stops if the game is paused or runs
+        slower/faster if the game-speed is modified. See RealTimer for a timer class which doesn't depend
+        on the game time.
     */
-    class _ToolsExport Timer : public TimeFactorListener
+    class _ToolsExport Timer : virtual public OrxonoxClass
     {
         public:
@@ -123,26 +131,26 @@
             void run();
 
-            /// Re-starts the Timer: The executor will be called after @a interval seconds.
+            /// Re-starts the timer: The executor will be called after @a interval seconds.
             inline void startTimer()
                 { this->bActive_ = true; this->time_ = this->interval_; }
-            /// Stops the Timer.
+            /// Stops the timer.
             inline void stopTimer()
                 { this->bActive_ = false; this->time_ = this->interval_; }
-            /// Pauses the Timer - it will continue with the actual state if you call unpauseTimer().
+            /// Pauses the timer - it will continue with the actual state if you call unpauseTimer().
             inline void pauseTimer()
                 { this->bActive_ = false; }
-            /// Unpauses the Timer - continues with the given state.
+            /// Unpauses the timer - continues with the given state.
             inline void unpauseTimer()
                 { this->bActive_ = true; }
-            /// Returns true if the Timer is active (neither stopped nor paused).
+            /// Returns true if the timer is active (neither stopped nor paused).
             inline bool isActive() const
                 { return this->bActive_; }
-            /// Returns the remaining time until the Timer calls the executor.
+            /// Returns the remaining time until the timer calls the executor.
             inline float getRemainingTime() const
                 { return static_cast<float>(this->time_ / 1000000.0f); }
-            /// Increases the remaining time of the Timer by the given amount of time (in seconds).
+            /// Increases the remaining time of the timer by the given amount of time (in seconds).
             inline void addTime(float time)
                 { if (time > 0.0f) this->time_ += static_cast<long long>(time * 1000000.0f); }
-            /// Decreases the remaining time of the Timer by the given amount of time (in seconds)
+            /// Decreases the remaining time of the timer by the given amount of time (in seconds)
             inline void removeTime(float time)
                 { if (time > 0.0f) this->time_ -= static_cast<long long>(time * 1000000.0f); }
@@ -156,4 +164,7 @@
             void tick(const Clock& time);
 
+        protected:
+            virtual float getTimeFactor();
+
         private:
             void init();
@@ -163,9 +174,25 @@
             long long interval_;    //!< The time-interval in micro seconds
             bool bLoop_;            //!< If true, the executor gets called every @a interval seconds
-            bool bActive_;          //!< If true, the Timer ticks and calls the executor if the time's up
+            bool bActive_;          //!< If true, the timer ticks and calls the executor if the time's up
             bool bKillAfterCall_;   //!< If true the timer gets deleted after it expired and called the executor
 
             long long time_;        //!< Internal variable, counting the time untill the next executor-call
     };
+
+    /**
+        @brief RealTimer is a helper class that executes a function after a given amount of seconds in real-time.
+
+        The time interval of RealTimer doesn't depend on the game time, it will also call the function
+        if the game is paused. See Timer for a timer class that depends on the game time.
+    */
+    class _ToolsExport RealTimer : public Timer
+    {
+        public:
+            RealTimer();
+            RealTimer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall = false);
+
+        protected:
+            virtual float getTimeFactor();
+    };
 }
 
Index: code/trunk/src/libraries/tools/ToolsPrereqs.h
===================================================================
--- code/trunk/src/libraries/tools/ToolsPrereqs.h	(revision 7851)
+++ code/trunk/src/libraries/tools/ToolsPrereqs.h	(revision 8079)
@@ -85,4 +85,5 @@
     class Mesh;
     class ParticleInterface;
+    class RealTimer;
     class ResourceCollection;
     class ResourceLocation;
