Index: code/branches/objecthierarchy2/src/core/BaseObject.h
===================================================================
--- code/branches/objecthierarchy2/src/core/BaseObject.h	(revision 2368)
+++ code/branches/objecthierarchy2/src/core/BaseObject.h	(revision 2369)
@@ -196,4 +196,5 @@
     SUPER_FUNCTION(4, BaseObject, processEvent, false);
     SUPER_FUNCTION(6, BaseObject, changedMainState, false);
+    SUPER_FUNCTION(9, BaseObject, changedName, false);
 }
 
Index: code/branches/objecthierarchy2/src/core/Super.h
===================================================================
--- code/branches/objecthierarchy2/src/core/Super.h	(revision 2368)
+++ code/branches/objecthierarchy2/src/core/Super.h	(revision 2369)
@@ -259,4 +259,10 @@
     #define SUPER_changedOwner(classname, functionname, ...) \
         SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedOverlayGroup(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedName(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
     // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
 
@@ -501,4 +507,12 @@
             ()
         SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(8, changedOverlayGroup, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(9, changedName, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
         // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
 
@@ -552,4 +566,6 @@
     SUPER_INTRUSIVE_DECLARATION(changedMainState);
     SUPER_INTRUSIVE_DECLARATION(changedOwner);
+    SUPER_INTRUSIVE_DECLARATION(changedOverlayGroup);
+    SUPER_INTRUSIVE_DECLARATION(changedName);
     // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
 
Index: code/branches/objecthierarchy2/src/core/Template.cc
===================================================================
--- code/branches/objecthierarchy2/src/core/Template.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/core/Template.cc	(revision 2369)
@@ -72,4 +72,6 @@
     void Template::changedName()
     {
+        SUPER(Template, changedName);
+
         if (this->getName() != "")
         {
Index: code/branches/objecthierarchy2/src/orxonox/CMakeLists.txt
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/CMakeLists.txt	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/CMakeLists.txt	(revision 2369)
@@ -4,4 +4,5 @@
   LevelManager.cc
   Main.cc
+  PawnManager.cc
   PlayerManager.cc
   Settings.cc
Index: code/branches/objecthierarchy2/src/orxonox/CameraManager.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/CameraManager.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/CameraManager.cc	(revision 2369)
@@ -30,8 +30,11 @@
 
 #include <OgreViewport.h>
+#include <OgreSceneManager.h>
+#include <OgreCamera.h>
 
 #include "core/Core.h"
 #include "objects/worldentities/Camera.h"
-
+#include "objects/Scene.h"
+#include "util/String.h"
 
 namespace orxonox
@@ -44,4 +47,6 @@
         assert(singletonRef_s == 0);
         singletonRef_s = this;
+
+        this->fallbackCamera_ = 0;
     }
 
@@ -50,4 +55,10 @@
         assert(singletonRef_s != 0);
         singletonRef_s = 0;
+
+        if (this->fallbackCamera_)
+        {
+            this->fallbackCamera_->getSceneManager()->destroyCamera(this->fallbackCamera_);
+COUT(0) << "remove camera-manager" << std::endl;
+        }
     }
 
@@ -68,14 +79,19 @@
         if (this->cameraList_.size() > 0)
             this->cameraList_.front()->removeFocus();
+        else if (this->fallbackCamera_)
+        {
+            this->fallbackCamera_->getSceneManager()->destroyCamera(this->fallbackCamera_);
+            this->fallbackCamera_ = 0;
+COUT(0) << "remove fallback camera" << std::endl;
+        }
 
         camera->setFocus(this->viewport_);
 
+        // make sure we don't add it twice
+        for (std::list<Camera*>::iterator it = this->cameraList_.begin(); it != this->cameraList_.end(); ++it)
+            if ((*it) == camera)
+                return;
+
         // add to list
-        std::list<Camera*>::iterator it;
-        for (it = this->cameraList_.begin(); it != this->cameraList_.end(); ++it)
-        {
-            if ((*it) == camera)
-                return; // make sure we don't add it twice
-        }
         this->cameraList_.push_front(camera);
     }
@@ -92,7 +108,18 @@
             this->cameraList_.pop_front();
 
-            // set new focus if necessary
-            if (cameraList_.size() > 0)
-                cameraList_.front()->setFocus(this->viewport_);
+            // set new focus if possible
+            if (this->cameraList_.size() > 0)
+                this->cameraList_.front()->setFocus(this->viewport_);
+            else
+            {
+                // there are no more cameras, create a fallback
+                if (!this->fallbackCamera_)
+                {
+COUT(0) << "create fallback camera" << std::endl;
+                    this->fallbackCamera_ = camera->getScene()->getSceneManager()->createCamera(getUniqueNumberString());
+                }
+                this->viewport_->setCamera(this->fallbackCamera_);
+COUT(0) << "use fallback camera" << std::endl;
+            }
         }
         else
Index: code/branches/objecthierarchy2/src/orxonox/CameraManager.h
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/CameraManager.h	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/CameraManager.h	(revision 2369)
@@ -62,4 +62,5 @@
             std::list<Camera*> cameraList_;
             Ogre::Viewport* viewport_;
+            Ogre::Camera* fallbackCamera_;
 
             static CameraManager* singletonRef_s;
Index: code/branches/objecthierarchy2/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/OrxonoxPrereqs.h	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/OrxonoxPrereqs.h	(revision 2369)
@@ -82,4 +82,5 @@
     class CameraManager;
     class LevelManager;
+    class PawnManager;
     class PlayerManager;
 
@@ -179,4 +180,5 @@
     class HUDRadar;
     class HUDSpeedBar;
+    class HUDHealthBar;
     class InGameConsole;
     class OrxonoxOverlay;
Index: code/branches/objecthierarchy2/src/orxonox/PawnManager.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/PawnManager.cc	(revision 2369)
+++ code/branches/objecthierarchy2/src/orxonox/PawnManager.cc	(revision 2369)
@@ -0,0 +1,74 @@
+/*
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "PawnManager.h"
+
+#include "core/CoreIncludes.h"
+#include "objects/worldentities/pawns/Pawn.h"
+
+
+namespace orxonox
+{
+    PawnManager* PawnManager::singletonRef_s = 0;
+
+    PawnManager::PawnManager()
+    {
+        RegisterRootObject(PawnManager);
+
+        assert(PawnManager::singletonRef_s == 0);
+        PawnManager::singletonRef_s = this;
+    }
+
+    PawnManager::~PawnManager()
+    {
+        assert(PawnManager::singletonRef_s != 0);
+        PawnManager::singletonRef_s = 0;
+    }
+
+    void PawnManager::touch()
+    {
+        if (!PawnManager::singletonRef_s)
+            new PawnManager();
+    }
+
+    void PawnManager::tick(float dt)
+    {
+        unsigned int count = 0;
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++count)
+        {
+            if (!it->isAlive())
+                delete (*(it++));
+            else
+                ++it;
+        }
+
+        if (count == 0)
+            delete this;
+    }
+}
Index: code/branches/objecthierarchy2/src/orxonox/PawnManager.h
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/PawnManager.h	(revision 2369)
+++ code/branches/objecthierarchy2/src/orxonox/PawnManager.h	(revision 2369)
@@ -0,0 +1,52 @@
+/*
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PawnManager_H__
+#define _PawnManager_H__
+
+#include "OrxonoxPrereqs.h"
+#include "objects/Tickable.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport PawnManager : public Tickable
+    {
+        public:
+            static void touch();
+
+            virtual void tick(float dt);
+
+        private:
+            PawnManager();
+            virtual ~PawnManager();
+
+            static PawnManager* singletonRef_s;
+    };
+}
+
+#endif /* _PawnManager_H__ */
Index: code/branches/objecthierarchy2/src/orxonox/objects/EventTarget.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/objects/EventTarget.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/objects/EventTarget.cc	(revision 2369)
@@ -48,4 +48,6 @@
     void EventTarget::changedName()
     {
+        SUPER(EventTarget, changedName);
+
         for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); ++it)
             if (it->getName() == this->getName())
Index: code/branches/objecthierarchy2/src/orxonox/objects/gametypes/Gametype.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/objects/gametypes/Gametype.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/objects/gametypes/Gametype.cc	(revision 2369)
@@ -169,19 +169,24 @@
         for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
         {
-            if (!it->first->getControllableEntity() && (!it->first->isReadyToSpawn() || !this->bStarted_))
-            {
-                SpawnPoint* spawn = this->getBestSpawnPoint(it->first);
-                if (spawn)
-                {
-                    // force spawn at spawnpoint with default pawn
-                    ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
-                    spawn->spawn(entity);
-                    it->first->startControl(entity);
-                    it->second = PlayerState::Dead;
-                }
-                else
-                {
-                    COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
-                    abort();
+            if (!it->first->getControllableEntity())
+            {
+                it->second = PlayerState::Dead;
+
+                if (!it->first->isReadyToSpawn() || !this->bStarted_)
+                {
+                    SpawnPoint* spawn = this->getBestSpawnPoint(it->first);
+                    if (spawn)
+                    {
+                        // force spawn at spawnpoint with default pawn
+                        ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
+                        spawn->spawn(entity);
+                        it->first->startControl(entity);
+                        it->second = PlayerState::Dead;
+                    }
+                    else
+                    {
+                        COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
+                        abort();
+                    }
                 }
             }
@@ -211,10 +216,13 @@
                 {
                     bool allplayersready = true;
+                    bool hashumanplayers = false;
                     for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
                     {
                         if (!it->first->isReadyToSpawn())
                             allplayersready = false;
-                    }
-                    if (allplayersready)
+                        if (it->first->isHumanPlayer())
+                            hashumanplayers = true;
+                    }
+                    if (allplayersready && hashumanplayers)
                     {
                         this->startCountdown_ = this->initialStartCountdown_;
Index: code/branches/objecthierarchy2/src/orxonox/objects/infos/PlayerInfo.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/objects/infos/PlayerInfo.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/objects/infos/PlayerInfo.cc	(revision 2369)
@@ -77,4 +77,6 @@
     void PlayerInfo::changedName()
     {
+        SUPER(PlayerInfo, changedName);
+
         if (this->isInitialized() && this->getGametype())
             this->getGametype()->playerChangedName(this);
Index: code/branches/objecthierarchy2/src/orxonox/objects/worldentities/Camera.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/objects/worldentities/Camera.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/objects/worldentities/Camera.cc	(revision 2369)
@@ -54,5 +54,5 @@
     {
         RegisterObject(Camera);
-
+COUT(0) << this << ": created camera" << std::endl;
         if (!this->getScene() || !this->getScene()->getSceneManager())
             ThrowException(AbortLoading, "Can't create Camera, no scene or no scene manager given.");
@@ -70,5 +70,5 @@
         this->configvaluecallback_changedNearClipDistance();
 
-        this->requestFocus(); // ! HACK ! REMOVE THIS !
+//        this->requestFocus(); // ! HACK ! REMOVE THIS !
     }
 
@@ -80,4 +80,5 @@
             this->getScene()->getSceneManager()->destroyCamera(this->camera_);
         }
+COUT(0) << this << ": destroyed camera" << std::endl;
     }
 
@@ -122,4 +123,5 @@
     void Camera::removeFocus()
     {
+COUT(0) << this << ": remove focus" << std::endl;
         this->bHasFocus_ = false;
     }
@@ -142,4 +144,5 @@
         this->bHasFocus_ = true;
         viewport->setCamera(this->camera_);
+COUT(0) << this << ": set focus" << std::endl;
 
         // reactivate all visible compositors
Index: code/branches/objecthierarchy2/src/orxonox/objects/worldentities/pawns/Pawn.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/objects/worldentities/pawns/Pawn.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/objects/worldentities/pawns/Pawn.cc	(revision 2369)
@@ -33,4 +33,5 @@
 #include "core/XMLPort.h"
 #include "util/Math.h"
+#include "PawnManager.h"
 #include "objects/infos/PlayerInfo.h"
 #include "objects/gametypes/Gametype.h"
@@ -45,5 +46,7 @@
         RegisterObject(Pawn);
 
-        this->bAlive_ = false;
+        PawnManager::touch();
+
+        this->bAlive_ = true;
 
         this->health_ = 0;
@@ -70,4 +73,9 @@
     Pawn::~Pawn()
     {
+        if (this->isInitialized())
+        {
+            for (ObjectList<PawnListener>::iterator it = ObjectList<PawnListener>::begin(); it != ObjectList<PawnListener>::end(); ++it)
+                it->destroyedPawn(this);
+        }
     }
 
@@ -76,5 +84,5 @@
         SUPER(Pawn, XMLPort, xmlelement, mode);
 
-        XMLPortParam(Pawn, "health", setHealth, getHealht, xmlelement, mode).defaultValues(100);
+        XMLPortParam(Pawn, "health", setHealth, getHealth, xmlelement, mode).defaultValues(100);
         XMLPortParam(Pawn, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
         XMLPortParam(Pawn, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
@@ -85,4 +93,5 @@
         REGISTERDATA(this->bAlive_, direction::toclient);
         REGISTERDATA(this->health_, direction::toclient);
+        REGISTERDATA(this->initialHealth_, direction::toclient);
     }
 
@@ -90,4 +99,6 @@
     {
         SUPER(Pawn, tick, dt);
+
+        this->health_ -= 15 * dt * rnd();
 
         if (this->health_ <= 0)
@@ -129,11 +140,14 @@
     void Pawn::death()
     {
+        // Set bAlive_ to false and wait for PawnManager to do the destruction
         this->bAlive_ = false;
+
         if (this->getGametype())
             this->getGametype()->pawnKilled(this, this->lastHitOriginator_);
+
+        this->setDestroyWhenPlayerLeft(false);
+
         if (this->getPlayer())
             this->getPlayer()->stopControl(this);
-
-        delete this;
 
         // play death effect
@@ -151,3 +165,11 @@
         this->spawn();
     }
+
+    ///////////////////
+    // Pawn Listener //
+    ///////////////////
+    PawnListener::PawnListener()
+    {
+        RegisterRootObject(PawnListener);
+    }
 }
Index: code/branches/objecthierarchy2/src/orxonox/objects/worldentities/pawns/Pawn.h
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/objects/worldentities/pawns/Pawn.h	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/objects/worldentities/pawns/Pawn.h	(revision 2369)
@@ -55,5 +55,5 @@
             inline void removeHealth(float health)
                 { this->setHealth(this->health_ - health); }
-            inline float getHealht() const
+            inline float getHealth() const
                 { return this->health_; }
 
@@ -96,4 +96,16 @@
             WeaponSystem* weaponSystem_;
     };
+
+    class _OrxonoxExport PawnListener : public OrxonoxClass
+    {
+        friend class Pawn;
+
+        public:
+            PawnListener();
+            virtual ~PawnListener() {}
+
+        protected:
+            virtual void destroyedPawn(Pawn* pawn) = 0;
+    };
 }
 
Index: code/branches/objecthierarchy2/src/orxonox/overlays/OrxonoxOverlay.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 2369)
@@ -62,14 +62,8 @@
 
         this->owner_ = 0;
+        this->group_ = 0;
 
         if (!Core::showsGraphics())
             ThrowException(NoGraphics, "Can't create OrxonoxOverlay, graphics engine not initialized");
-
-        // add this overlay to the static map of OrxonoxOverlays
-        if (overlays_s.find(this->getName()) != overlays_s.end())
-        {
-            COUT(1) << "Overlay names should be unique or you cannnot access them via console. Name: \"" << this->getName() << "\"" << std::endl;
-        }
-        overlays_s[this->getName()] = this;
 
         // create the Ogre::Overlay
@@ -132,8 +126,8 @@
 
         XMLPortParam(OrxonoxOverlay, "size",      setSize,      getSize,      xmlElement, mode);
-        XMLPortParam(OrxonoxOverlay, "pickPoint", setPickPoint, getPickPoint, xmlElement, mode);
+        XMLPortParam(OrxonoxOverlay, "pickpoint", setPickPoint, getPickPoint, xmlElement, mode);
         XMLPortParam(OrxonoxOverlay, "position",  setPosition,  getPosition,  xmlElement, mode);
         XMLPortParam(OrxonoxOverlay, "rotation",  setRotation,  getRotation,  xmlElement, mode);
-        XMLPortParam(OrxonoxOverlay, "correctAspect", setAspectCorrection,   getAspectCorrection,   xmlElement, mode);
+        XMLPortParam(OrxonoxOverlay, "correctaspect", setAspectCorrection,   getAspectCorrection,   xmlElement, mode);
         XMLPortParam(OrxonoxOverlay, "background",    setBackgroundMaterial, getBackgroundMaterial, xmlElement, mode);
     }
@@ -141,4 +135,6 @@
     void OrxonoxOverlay::changedName()
     {
+        SUPER(OrxonoxOverlay, changedName);
+
         OrxonoxOverlay::overlays_s.erase(this->getOldName());
 
Index: code/branches/objecthierarchy2/src/orxonox/overlays/OrxonoxOverlay.h
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/OrxonoxOverlay.h	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/OrxonoxOverlay.h	(revision 2369)
@@ -125,5 +125,5 @@
 
         //! Gets the rotation angle applied to this overlay in degrees.
-        const Radian& getRotation() const         { return this->angle_; }
+        const Degree& getRotation() const         { return this->angle_; }
 
         //! Rotates the overlay by angle degrees.
@@ -166,4 +166,16 @@
         virtual void changedOwner() {}
 
+        inline void setOverlayGroup(OverlayGroup* group)
+        {
+            if (group != this->group_)
+            {
+                this->group_ = group;
+                this->changedOverlayGroup();
+            }
+        }
+        inline OverlayGroup* getOverlayGroup() const
+            { return this->group_; }
+        virtual void changedOverlayGroup() {}
+
     protected:
         virtual void angleChanged();
@@ -184,5 +196,5 @@
         Vector2 position_;                         //!< Position of the pickPoint on the screen.
         Vector2 pickPoint_;                        //!< Point on the overlay to pick when translating
-        Radian angle_;                             //!< Rotation angle of the overlay
+        Degree angle_;                             //!< Rotation angle of the overlay
         RotationState rotState_;             //!< horizontal, vertical or inbetween
 
@@ -195,7 +207,9 @@
         static std::map<std::string, OrxonoxOverlay*> overlays_s;
         ControllableEntity* owner_;
+        OverlayGroup* group_;
   };
 
   SUPER_FUNCTION(7, OrxonoxOverlay, changedOwner, false);
+  SUPER_FUNCTION(8, OrxonoxOverlay, changedOverlayGroup, false);
 }
 
Index: code/branches/objecthierarchy2/src/orxonox/overlays/OverlayGroup.h
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/OverlayGroup.h	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/OverlayGroup.h	(revision 2369)
@@ -73,5 +73,4 @@
             { return this->owner_; }
 
-    private:
         //! Scales each OrxonoxOverlay individually by scale.
         void scale(const Vector2& scale) { this->setScale(scale * this->scale_); }
@@ -89,4 +88,5 @@
         OrxonoxOverlay* getElement(unsigned int index);
 
+    private:
         std::map<std::string, OrxonoxOverlay*> hudElements_;    //!< Contains all the OrxonoxOverlays of the this group.
         Vector2 scale_;                                         //!< Current scale (independant of the elements).
Index: code/branches/objecthierarchy2/src/orxonox/overlays/OverlayText.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/OverlayText.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/OverlayText.cc	(revision 2369)
@@ -50,9 +50,9 @@
         this->text_->setCharHeight(1.0);
 
-        setFont("Monofur");
-        setColour(ColourValue(1.0, 1.0, 1.0, 1.0));
-        setCaption("");
-        setTextSize(1.0f);
-        setAlignmentString("left");
+        this->setFont("Monofur");
+        this->setColour(ColourValue(1.0, 1.0, 1.0, 1.0));
+        this->setCaption("");
+        this->setTextSize(1.0f);
+        this->setAlignmentString("left");
 
         this->background_->addChild(this->text_);
@@ -69,9 +69,10 @@
         SUPER(OverlayText, XMLPort, xmlElement, mode);
 
-        XMLPortParam(OverlayText, "font",     setFont,            getFont,            xmlElement, mode);
-        XMLPortParam(OverlayText, "colour",   setColour,          getColour,          xmlElement, mode);
-        XMLPortParam(OverlayText, "caption",  setCaption,         getCaption,         xmlElement, mode);
-        XMLPortParam(OverlayText, "textSize", setTextSize,        getTextSize,        xmlElement, mode);
-        XMLPortParam(OverlayText, "align",    setAlignmentString, getAlignmentString, xmlElement, mode);
+        XMLPortParam(OverlayText, "font",       setFont,            getFont,            xmlElement, mode);
+        XMLPortParam(OverlayText, "colour",     setColour,          getColour,          xmlElement, mode);
+        XMLPortParam(OverlayText, "caption",    setCaption,         getCaption,         xmlElement, mode);
+        XMLPortParam(OverlayText, "textsize",   setTextSize,        getTextSize,        xmlElement, mode);
+        XMLPortParam(OverlayText, "align",      setAlignmentString, getAlignmentString, xmlElement, mode);
+        XMLPortParam(OverlayText, "spacewidth", setSpaceWidth,      getSpaceWidth,      xmlElement, mode);
     }
 
Index: code/branches/objecthierarchy2/src/orxonox/overlays/OverlayText.h
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/OverlayText.h	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/OverlayText.h	(revision 2369)
@@ -47,24 +47,27 @@
         virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
 
-        void setCaption(const std::string& caption) { this->text_->setCaption(caption); }
-        std::string getCaption() const              { return this->text_->getCaption(); }
+        inline void setCaption(const std::string& caption) { this->text_->setCaption(caption); }
+        inline std::string getCaption() const              { return this->text_->getCaption(); }
 
         void setFont(const std::string& font);
-        const std::string& getFont() const { return this->text_->getFontName(); }
+        inline const std::string& getFont() const { return this->text_->getFontName(); }
 
-        void setColour(const ColourValue& colour) { this->text_->setColour(colour); }
-        const ColourValue& getColour() const      { return this->text_->getColour(); }
+        inline void setSpaceWidth(float width) { this->text_->setSpaceWidth(width); }
+        inline float getSpaceWidth() const     { return this->text_->getSpaceWidth(); }
 
-        void setAlignment(Ogre::TextAreaOverlayElement::Alignment alignment) { this->text_->setAlignment(alignment); }
-        Ogre::TextAreaOverlayElement::Alignment getAlignment() const         { return this->text_->getAlignment(); }
+        inline void setColour(const ColourValue& colour) { this->text_->setColour(colour); }
+        inline const ColourValue& getColour() const      { return this->text_->getColour(); }
 
-    protected:
-        virtual void sizeChanged();
+        inline void setAlignment(Ogre::TextAreaOverlayElement::Alignment alignment) { this->text_->setAlignment(alignment); }
+        inline Ogre::TextAreaOverlayElement::Alignment getAlignment() const         { return this->text_->getAlignment(); }
 
         void setAlignmentString(const std::string& alignment);
         std::string getAlignmentString() const;
 
-        void setTextSize(float size) { this->setSize(Vector2(size, size)); }
-        float getTextSize() const    { return this->getSize().y; }
+        inline void setTextSize(float size) { this->setSize(Vector2(size, size)); }
+        inline float getTextSize() const    { return this->getSize().y; }
+
+    protected:
+        virtual void sizeChanged();
 
         Ogre::TextAreaOverlayElement* text_;
Index: code/branches/objecthierarchy2/src/orxonox/overlays/hud/CMakeLists.txt
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/hud/CMakeLists.txt	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/hud/CMakeLists.txt	(revision 2369)
@@ -4,4 +4,5 @@
   HUDRadar.cc
   HUDSpeedBar.cc
+  HUDHealthBar.cc
   ChatOverlay.cc
 )
Index: code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDBar.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDBar.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDBar.cc	(revision 2369)
@@ -51,6 +51,6 @@
         RegisterObject(BarColour);
 
-        setColour(ColourValue(1.0, 1.0, 1.0, 1.0));
-        setPosition(0.0);
+        this->setColour(ColourValue(1.0, 1.0, 1.0, 1.0));
+        this->setPosition(0.0);
     }
 
@@ -84,7 +84,8 @@
         this->bar_->setMaterialName(materialname);
 
-        setValue(0.4567654f);
-        setRightToLeft(false);
-        setAutoColour(true);
+        this->setValue(0.0f);
+        this->setRightToLeft(false);
+        this->setAutoColour(true);
+        this->currentColour_ = ColourValue::White;
 
         this->background_->addChild(bar_);
@@ -101,7 +102,8 @@
         SUPER(HUDBar, XMLPort, xmlElement, mode);
 
-        XMLPortParam(HUDBar, "initialValue", setValue,       getValue,       xmlElement, mode);
-        XMLPortParam(HUDBar, "rightToLeft",  setRightToLeft, getRightToLeft, xmlElement, mode);
-        XMLPortParam(HUDBar, "autoColour",   setAutoColour,  getAutoColour,  xmlElement, mode);
+        XMLPortParam(HUDBar, "initialvalue", setValue,       getValue,       xmlElement, mode);
+        XMLPortParam(HUDBar, "righttoleft",  setRightToLeft, getRightToLeft, xmlElement, mode);
+        XMLPortParam(HUDBar, "autocolour",   setAutoColour,  getAutoColour,  xmlElement, mode);
+        XMLPortParam(HUDBar, "bartexture",   setBarTexture,  getBarTexture, xmlElement, mode);
         XMLPortObject(HUDBar, BarColour, "", addColour, getColour, xmlElement, mode);
     }
@@ -130,8 +132,10 @@
                 {
                     this->textureUnitState_->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, colour2);
+                    this->currentColour_ = colour2;
                 }
                 else if (value1 < this->value_)
                 {
                     this->textureUnitState_->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, colour1);
+                    this->currentColour_ = colour1;
                 }
                 else
@@ -139,5 +143,7 @@
                     //float interpolationfactor = (this->value_ - value2) / (value1 - value2);
                     float interpolationfactor = interpolateSmooth((this->value_ - value2) / (value1 - value2), 0.0f, 1.0f);
-                    this->textureUnitState_->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, colour1 * interpolationfactor + colour2 * (1 - interpolationfactor));
+                    this->currentColour_ = colour1 * interpolationfactor + colour2 * (1 - interpolationfactor);
+                    this->textureUnitState_->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, this->currentColour_);
+
                 }
             }
@@ -181,3 +187,13 @@
         this->colours_.clear();
     }
+
+    void HUDBar::setBarTexture(const std::string& texture)
+    {
+        this->textureUnitState_->setTextureName(texture);
+    }
+
+    const std::string& HUDBar::getBarTexture() const
+    {
+        return this->textureUnitState_->getTextureName();
+    }
 }
Index: code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDBar.h
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDBar.h	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDBar.h	(revision 2369)
@@ -71,12 +71,46 @@
         void clearColours();
 
-        void setRightToLeft(bool r2l) { this->right2Left_ = r2l; this->valueChanged(); }
-        bool getRightToLeft() const   { return this->right2Left_; }
+        inline void setRightToLeft(bool r2l)
+        {
+            if (r2l != this->right2Left_)
+            {
+                this->right2Left_ = r2l;
+                this->valueChanged();
+            }
+        }
+        inline bool getRightToLeft() const
+            { return this->right2Left_; }
 
-        void setValue(float value)    { this->value_ = clamp(value, 0.0f, 1.0f); this->valueChanged(); }
-        float getValue() const        { return this->value_; }
+        inline void setValue(float value)
+        {
+            float temp = clamp(value, 0.0f, 1.0f);
+            if (temp != this->value_)
+            {
+                this->value_ = temp;
+                this->valueChanged();
+            }
+        }
+        inline float getValue() const
+            { return this->value_; }
 
-        void setAutoColour(bool val)  { this->autoColour_ = val; this->valueChanged(); }
-        bool getAutoColour() const    { return this->autoColour_; }
+        inline void setAutoColour(bool val)
+        {
+            if (val != this->autoColour_)
+            {
+                this->autoColour_ = val;
+                this->valueChanged();
+
+                if (!val)
+                    this->currentColour_ = ColourValue::White;
+            }
+        }
+        inline bool getAutoColour() const
+            { return this->autoColour_; }
+
+        void setBarTexture(const std::string& texture);
+        const std::string& getBarTexture() const;
+
+        inline const ColourValue& getCurrentBarColour() const
+            { return this->currentColour_; }
 
     protected:
@@ -90,4 +124,5 @@
         bool autoColour_;                   //!< whether bar changes colour automatically
         float value_;                       //!< progress of bar
+        ColourValue currentColour_;
 
         Ogre::PanelOverlayElement* bar_;
Index: code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDHealthBar.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDHealthBar.cc	(revision 2369)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDHealthBar.cc	(revision 2369)
@@ -0,0 +1,138 @@
+/*
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "HUDHealthBar.h"
+
+#include <OgreOverlayManager.h>
+#include <OgrePanelOverlayElement.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "objects/worldentities/pawns/Pawn.h"
+#include "objects/items/Engine.h"
+#include "overlays/OverlayGroup.h"
+#include "util/Convert.h"
+
+namespace orxonox
+{
+    CreateFactory(HUDHealthBar);
+
+    HUDHealthBar::HUDHealthBar(BaseObject* creator) : HUDBar(creator)
+    {
+        RegisterObject(HUDHealthBar);
+
+        this->owner_ = 0;
+        this->bUseBarColour_ = false;
+
+        this->textoverlay_ = new OverlayText(this);
+
+        assert(this->textoverlay_);
+
+        this->textoverlay_->setCaption("");
+    }
+
+    HUDHealthBar::~HUDHealthBar()
+    {
+        if (this->isInitialized())
+            delete this->textoverlay_;
+    }
+
+    void HUDHealthBar::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(HUDHealthBar, XMLPort, xmlelement, mode);
+
+        XMLPortParam(HUDHealthBar, "showtext",          setTextVisible,          getTextVisible,          xmlelement, mode).defaultValues(true);
+        XMLPortParam(HUDHealthBar, "textfont",          setTextFont,             getTextFont,             xmlelement, mode).defaultValues("Monofur");
+        XMLPortParam(HUDHealthBar, "textusebarcolour",  setTextUseBarColour,     getTextUseBarColour,     xmlelement, mode).defaultValues(false);
+        XMLPortParam(HUDHealthBar, "textcolour",        setTextColour,           getTextColour,           xmlelement, mode).defaultValues(ColourValue(1.0, 1.0, 1.0, 1.0));
+        XMLPortParam(HUDHealthBar, "textsize",          setTextSize,             getTextSize,             xmlelement, mode).defaultValues(1.0f);
+        XMLPortParam(HUDHealthBar, "textalign",         setTextAlignmentString,  getTextAlignmentString,  xmlelement, mode).defaultValues("left");
+        XMLPortParam(HUDHealthBar, "textoffset",        setTextOffset,           getTextOffset,           xmlelement, mode).defaultValues(Vector2::ZERO);
+        XMLPortParam(HUDHealthBar, "textpickpoint",     setTextPickPoint,        getTextPickPoint,        xmlelement, mode).defaultValues(Vector2::ZERO);
+        XMLPortParam(HUDHealthBar, "textrotation",      setTextRotation,         getTextRotation,         xmlelement, mode).defaultValues(0.0f);
+        XMLPortParam(HUDHealthBar, "textcorrectaspect", setTextAspectCorrection, getTextAspectCorrection, xmlelement, mode).defaultValues(true);
+        XMLPortParam(HUDHealthBar, "textspacewidth",    setTextSpaceWidth,       getTextSpaceWidth,       xmlelement, mode).defaultValues(true);
+    }
+
+    void HUDHealthBar::tick(float dt)
+    {
+        SUPER(HUDHealthBar, tick, dt);
+
+        if (this->owner_)
+        {
+            this->setValue(this->owner_->getHealth() / this->owner_->getInitialHealth());
+            this->textoverlay_->setCaption(convertToString((int)this->owner_->getHealth()));
+        }
+
+        if (this->bUseBarColour_)
+            this->textoverlay_->setColour(this->getCurrentBarColour());
+    }
+
+    void HUDHealthBar::changedOwner()
+    {
+        SUPER(HUDHealthBar, changedOwner);
+
+        this->owner_ = dynamic_cast<Pawn*>(this->getOwner());
+    }
+
+    void HUDHealthBar::changedOverlayGroup()
+    {
+        SUPER(HUDHealthBar, changedOverlayGroup);
+
+        this->getOverlayGroup()->addElement(this->textoverlay_);
+    }
+
+    void HUDHealthBar::changedVisibility()
+    {
+        SUPER(HUDHealthBar, changedVisibility);
+
+        this->textoverlay_->setVisible(this->isVisible());
+    }
+
+    void HUDHealthBar::changedName()
+    {
+        SUPER(HUDHealthBar, changedName);
+
+        this->textoverlay_->setName(this->getName() + "text");
+    }
+
+    void HUDHealthBar::setTextColour(const ColourValue& colour)
+    {
+        this->textColour_ = colour;
+        if (!this->bUseBarColour_)
+            this->textoverlay_->setColour(colour);
+    }
+
+    void HUDHealthBar::setTextUseBarColour(bool bUseBarColour)
+    {
+        this->bUseBarColour_ = bUseBarColour;
+        if (!bUseBarColour)
+            this->textoverlay_->setColour(this->textColour_);
+    }
+}
Index: code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDHealthBar.h
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDHealthBar.h	(revision 2369)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDHealthBar.h	(revision 2369)
@@ -0,0 +1,118 @@
+/*
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _HUDHealthBar_H__
+#define _HUDHealthBar_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "HUDBar.h"
+#include "objects/Tickable.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport HUDHealthBar : public HUDBar, public Tickable
+    {
+        public:
+            HUDHealthBar(BaseObject* creator);
+            ~HUDHealthBar();
+
+            virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+            virtual void changedOwner();
+            virtual void changedOverlayGroup();
+            virtual void changedVisibility();
+            virtual void changedName();
+
+            inline void setTextFont(const std::string& font)
+                { if (font != "") { this->textoverlay_->setFont(font); } }
+            inline const std::string& getTextFont() const
+                { return this->textoverlay_->getFont(); }
+
+            void setTextColour(const ColourValue& colour);
+            inline const ColourValue& getTextColour() const
+                { return this->textoverlay_->getColour(); }
+
+            void setTextUseBarColour(bool bUseBarColour);
+            inline bool getTextUseBarColour() const
+                { return this->bUseBarColour_; }
+
+            inline void setTextAlignment(Ogre::TextAreaOverlayElement::Alignment alignment)
+                { this->textoverlay_->setAlignment(alignment); }
+            inline Ogre::TextAreaOverlayElement::Alignment getTextAlignment() const
+                { return this->textoverlay_->getAlignment(); }
+
+            void setTextAlignmentString(const std::string& alignment)
+                { this->textoverlay_->setAlignmentString(alignment); }
+            std::string getTextAlignmentString() const
+                { return this->textoverlay_->getAlignmentString(); }
+
+            inline void setTextSize(float size)
+                { this->textoverlay_->setTextSize(size); }
+            inline float getTextSize() const
+                { return this->textoverlay_->getTextSize(); }
+
+            inline void setTextVisible(bool bVisible)
+                { this->textoverlay_->setVisible(bVisible); }
+            inline bool getTextVisible() const
+                { return this->textoverlay_->isVisible(); }
+
+            inline void setTextPickPoint(const Vector2& pickpoint)
+                { this->textoverlay_->setPickPoint(pickpoint); }
+            inline Vector2 getTextPickPoint() const
+                { return this->textoverlay_->getPickPoint(); }
+
+            inline void setTextOffset(const Vector2& position)
+                { this->textoverlay_->setPosition(this->getPosition() + (position - this->getPickPoint()) * this->getSize()); }
+            inline Vector2 getTextOffset() const
+                { return (this->textoverlay_->getPosition() - this->getPosition()) / this->getSize() + this->getPickPoint(); }
+
+            inline void setTextAspectCorrection(bool correct)
+                { this->textoverlay_->setAspectCorrection(correct); }
+            inline bool getTextAspectCorrection() const
+                { return this->textoverlay_->getAspectCorrection(); }
+
+            inline void setTextRotation(const Degree& angle)
+                { this->textoverlay_->setRotation(angle); }
+            inline const Degree& getTextRotation() const
+                { return this->textoverlay_->getRotation(); }
+
+            inline void setTextSpaceWidth(float width)
+                { this->textoverlay_->setSpaceWidth(width); }
+            inline float getTextSpaceWidth() const
+                { return this->textoverlay_->getSpaceWidth(); }
+
+        private:
+            Pawn* owner_;
+            OverlayText* textoverlay_;
+            bool bUseBarColour_;
+            ColourValue textColour_;
+    };
+}
+#endif /* _HUDHealthBar_H__ */
Index: code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDSpeedBar.cc
===================================================================
--- code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDSpeedBar.cc	(revision 2368)
+++ code/branches/objecthierarchy2/src/orxonox/overlays/hud/HUDSpeedBar.cc	(revision 2369)
@@ -56,8 +56,6 @@
         if (this->owner_ && this->owner_->getEngine())
         {
-            float v = this->owner_->getVelocity().length();
-            float value = v / (this->owner_->getEngine()->getMaxSpeedFront() * this->owner_->getEngine()->getSpeedFactor() * this->owner_->getEngine()->getBoostFactor());
-            if (value != this->getValue())
-                this->setValue(value);
+            float value = this->owner_->getVelocity().length() / (this->owner_->getEngine()->getMaxSpeedFront() * this->owner_->getEngine()->getSpeedFactor() * this->owner_->getEngine()->getBoostFactor());
+            this->setValue(value);
         }
     }
