Index: code/trunk/src/orxonox/objects/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/objects/CMakeLists.txt	(revision 2809)
+++ code/trunk/src/orxonox/objects/CMakeLists.txt	(revision 2826)
@@ -8,4 +8,5 @@
   RadarListener.cc
   RadarViewable.cc
+  Teamcolourable.cc
   Tickable.cc
   Test.cc
Index: code/trunk/src/orxonox/objects/Level.cc
===================================================================
--- code/trunk/src/orxonox/objects/Level.cc	(revision 2809)
+++ code/trunk/src/orxonox/objects/Level.cc	(revision 2826)
@@ -105,17 +105,26 @@
     {
         Identifier* identifier = ClassByString(gametype);
-        if (identifier && identifier->isA(Class(Gametype)))
+
+        if (!identifier || !identifier->isA(Class(Gametype)))
         {
+            COUT(0) << "Error: \"" << gametype << "\" is not a valid gametype." << std::endl;
+            identifier = Class(Gametype);
+            this->gametype_ = "Gametype";
+        }
+        else
             this->gametype_ = gametype;
 
-            Gametype* rootgametype = dynamic_cast<Gametype*>(identifier->fabricate(this));
-            this->setGametype(rootgametype);
+std::cout << "Load Gametype: " << this->gametype_ << std::endl;
 
-            for (std::list<BaseObject*>::iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
-                (*it)->setGametype(rootgametype);
+        Gametype* rootgametype = dynamic_cast<Gametype*>(identifier->fabricate(this));
+        this->setGametype(rootgametype);
 
-            if (LevelManager::getInstancePtr())
-                LevelManager::getInstance().requestActivity(this);
-        }
+std::cout << "root gametype: " << rootgametype->getIdentifier()->getName() << std::endl;
+
+        for (std::list<BaseObject*>::iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
+            (*it)->setGametype(rootgametype);
+
+        if (LevelManager::getInstancePtr())
+            LevelManager::getInstance().requestActivity(this);
     }
 
Index: code/trunk/src/orxonox/objects/Teamcolourable.cc
===================================================================
--- code/trunk/src/orxonox/objects/Teamcolourable.cc	(revision 2826)
+++ code/trunk/src/orxonox/objects/Teamcolourable.cc	(revision 2826)
@@ -0,0 +1,39 @@
+/*
+ *   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 "Teamcolourable.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    Teamcolourable::Teamcolourable()
+    {
+        RegisterRootObject(Teamcolourable);
+    }
+}
Index: code/trunk/src/orxonox/objects/Teamcolourable.h
===================================================================
--- code/trunk/src/orxonox/objects/Teamcolourable.h	(revision 2826)
+++ code/trunk/src/orxonox/objects/Teamcolourable.h	(revision 2826)
@@ -0,0 +1,49 @@
+/*
+ *   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 _Teamcolourable_H__
+#define _Teamcolourable_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Teamcolourable : virtual public OrxonoxClass
+    {
+        public:
+            virtual void setTeamColour(const ColourValue& colour) = 0;
+
+        protected:
+            Teamcolourable();
+    };
+}
+
+#endif /* _Teamcolourable_H__ */
Index: code/trunk/src/orxonox/objects/controllers/Controller.cc
===================================================================
--- code/trunk/src/orxonox/objects/controllers/Controller.cc	(revision 2809)
+++ code/trunk/src/orxonox/objects/controllers/Controller.cc	(revision 2826)
@@ -43,40 +43,8 @@
         this->player_ = 0;
         this->controllableEntity_ = 0;
-        this->hud_ = 0;
-        this->bUpdateHUD_ = false;
     }
 
     Controller::~Controller()
     {
-        if (this->isInitialized() && this->hud_)
-            delete this->hud_;
-    }
-
-    void Controller::changedControllableEntity()
-    {
-        if (this->bUpdateHUD_)
-        {
-            this->updateHUD();
-            this->bUpdateHUD_ = false;
-        }
-
-        if (this->hud_)
-            this->hud_->setOwner(this->getControllableEntity());
-    }
-
-    void Controller::updateHUD()
-    {
-        if (this->hud_)
-        {
-            delete this->hud_;
-            this->hud_ = 0;
-        }
-
-        if (this->hudtemplate_ != "")
-        {
-            this->hud_ = new OverlayGroup(this);
-            this->hud_->addTemplate(this->hudtemplate_);
-            this->hud_->setOwner(this->getControllableEntity());
-        }
     }
 }
Index: code/trunk/src/orxonox/objects/controllers/Controller.h
===================================================================
--- code/trunk/src/orxonox/objects/controllers/Controller.h	(revision 2809)
+++ code/trunk/src/orxonox/objects/controllers/Controller.h	(revision 2826)
@@ -57,31 +57,9 @@
             inline ControllableEntity* getControllableEntity() const
                 { return this->controllableEntity_; }
-            virtual void changedControllableEntity();
-
-            inline void setHUDTemplate(const std::string& name)
-            {
-                if (name != this->hudtemplate_)
-                {
-                    this->hudtemplate_ = name;
-                    if (this->controllableEntity_)
-                        this->updateHUD();
-                    else
-                        this->bUpdateHUD_ = true;
-                }
-            }
-            inline const std::string& getHUDTemplate() const
-                { return this->hudtemplate_; }
-
-            inline OverlayGroup* getHUD() const
-                { return this->hud_; }
+            virtual void changedControllableEntity() {}
 
         protected:
-            void updateHUD();
-
             PlayerInfo* player_;
             ControllableEntity* controllableEntity_;
-            std::string hudtemplate_;
-            OverlayGroup* hud_;
-            bool bUpdateHUD_;
     };
 }
Index: code/trunk/src/orxonox/objects/gametypes/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/objects/gametypes/CMakeLists.txt	(revision 2809)
+++ code/trunk/src/orxonox/objects/gametypes/CMakeLists.txt	(revision 2826)
@@ -1,3 +1,6 @@
 ADD_SOURCE_FILES(ORXONOX_SRC_FILES
   Gametype.cc
+  Deathmatch.cc
+  TeamDeathmatch.cc
+  Pong.cc
 )
Index: code/trunk/src/orxonox/objects/gametypes/Deathmatch.cc
===================================================================
--- code/trunk/src/orxonox/objects/gametypes/Deathmatch.cc	(revision 2826)
+++ code/trunk/src/orxonox/objects/gametypes/Deathmatch.cc	(revision 2826)
@@ -0,0 +1,135 @@
+/*
+ *   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 "Deathmatch.h"
+
+#include "core/CoreIncludes.h"
+#include "objects/infos/PlayerInfo.h"
+#include "objects/worldentities/pawns/Pawn.h"
+
+#include "network/Host.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(Deathmatch);
+
+    Deathmatch::Deathmatch(BaseObject* creator) : Gametype(creator)
+    {
+        RegisterObject(Deathmatch);
+    }
+
+    void Deathmatch::start()
+    {
+        Gametype::start();
+
+        std::string message = "The match has started!";
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+
+    void Deathmatch::end()
+    {
+        Gametype::end();
+
+        std::string message = "The match has ended.";
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+
+    void Deathmatch::playerEntered(PlayerInfo* player)
+    {
+        Gametype::playerEntered(player);
+
+        std::string message = player->getName() + " entered the game";
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+
+    bool Deathmatch::playerLeft(PlayerInfo* player)
+    {
+        bool valid_player = Gametype::playerLeft(player);
+
+        if (valid_player)
+        {
+            std::string message = player->getName() + " left the game";
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+        }
+
+        return valid_player;
+    }
+
+    bool Deathmatch::playerChangedName(PlayerInfo* player)
+    {
+        bool valid_player = Gametype::playerChangedName(player);
+
+        if (valid_player)
+        {
+            std::string message = player->getOldName() + " changed name to " + player->getName();
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+        }
+
+        return valid_player;
+    }
+
+    void Deathmatch::pawnKilled(Pawn* victim, Pawn* killer)
+    {
+        if (victim && victim->getPlayer())
+        {
+            std::string message;
+            if (killer)
+            {
+                if (killer->getPlayer())
+                    message = victim->getPlayer()->getName() + " was killed by " + killer->getPlayer()->getName();
+                else
+                    message = victim->getPlayer()->getName() + " was killed";
+            }
+            else
+                message = victim->getPlayer()->getName() + " died";
+
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+        }
+
+        Gametype::pawnKilled(victim, killer);
+    }
+
+    void Deathmatch::playerScored(PlayerInfo* player)
+    {
+        Gametype::playerScored(player);
+
+        if (player)
+        {
+            std::string message = player->getName() + " scores!";
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+        }
+    }
+}
Index: code/trunk/src/orxonox/objects/gametypes/Deathmatch.h
===================================================================
--- code/trunk/src/orxonox/objects/gametypes/Deathmatch.h	(revision 2826)
+++ code/trunk/src/orxonox/objects/gametypes/Deathmatch.h	(revision 2826)
@@ -0,0 +1,55 @@
+/*
+ *   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 _Deathmatch_H__
+#define _Deathmatch_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "Gametype.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Deathmatch : public Gametype
+    {
+        public:
+            Deathmatch(BaseObject* creator);
+            virtual ~Deathmatch() {}
+
+            virtual void start();
+            virtual void end();
+            virtual void playerEntered(PlayerInfo* player);
+            virtual bool playerLeft(PlayerInfo* player);
+            virtual bool playerChangedName(PlayerInfo* player);
+
+            virtual void pawnKilled(Pawn* victim, Pawn* killer = 0);
+            virtual void playerScored(PlayerInfo* player);
+    };
+}
+
+#endif /* _Deathmatch_H__ */
Index: code/trunk/src/orxonox/objects/gametypes/Gametype.cc
===================================================================
--- code/trunk/src/orxonox/objects/gametypes/Gametype.cc	(revision 2809)
+++ code/trunk/src/orxonox/objects/gametypes/Gametype.cc	(revision 2826)
@@ -44,6 +44,4 @@
 #include "objects/worldentities/Camera.h"
 
-#include "network/Host.h"
-
 namespace orxonox
 {
@@ -65,6 +63,4 @@
 
         this->setConfigValues();
-
-        this->addBots(this->numberOfBots_);
 
         // load the corresponding score board
@@ -105,5 +101,6 @@
     void Gametype::start()
     {
-        COUT(0) << "game started" << std::endl;
+        this->addBots(this->numberOfBots_);
+
         this->gtinfo_.bStarted_ = true;
 
@@ -113,5 +110,4 @@
     void Gametype::end()
     {
-        COUT(0) << "game ended" << std::endl;
         this->gtinfo_.bEnded_ = true;
     }
@@ -120,11 +116,7 @@
     {
         this->players_[player].state_ = PlayerState::Joined;
-
-        std::string message = player->getName() + " entered the game";
-        COUT(0) << message << std::endl;
-        Host::Broadcast(message);
-    }
-
-    void Gametype::playerLeft(PlayerInfo* player)
+    }
+
+    bool Gametype::playerLeft(PlayerInfo* player)
     {
         std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
@@ -132,9 +124,7 @@
         {
             this->players_.erase(it);
-
-            std::string message = player->getName() + " left the game";
-            COUT(0) << message << std::endl;
-            Host::Broadcast(message);
-        }
+            return true;
+        }
+        return false;
     }
 
@@ -147,5 +137,5 @@
     }
 
-    void Gametype::playerChangedName(PlayerInfo* player)
+    bool Gametype::playerChangedName(PlayerInfo* player)
     {
         if (this->players_.find(player) != this->players_.end())
@@ -153,9 +143,8 @@
             if (player->getName() != player->getOldName())
             {
-                std::string message = player->getOldName() + " changed name to " + player->getName();
-                COUT(0) << message << std::endl;
-                Host::Broadcast(message);
-            }
-        }
+                return true;
+            }
+        }
+        return false;
     }
 
@@ -168,23 +157,37 @@
     }
 
+    void Gametype::playerPreSpawn(PlayerInfo* player)
+    {
+    }
+
+    void Gametype::playerPostSpawn(PlayerInfo* player)
+    {
+    }
+
+    void Gametype::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
+    {
+    }
+
+    void Gametype::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
+    {
+    }
+
+    bool Gametype::allowPawnHit(Pawn* victim, Pawn* originator)
+    {
+        return true;
+    }
+
+    bool Gametype::allowPawnDamage(Pawn* victim, Pawn* originator)
+    {
+        return true;
+    }
+
+    bool Gametype::allowPawnDeath(Pawn* victim, Pawn* originator)
+    {
+        return true;
+    }
+
     void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
     {
-        if (victim && victim->getPlayer())
-        {
-            std::string message;
-            if (killer)
-            {
-                if (killer->getPlayer())
-                    message = victim->getPlayer()->getName() + " was killed by " + killer->getPlayer()->getName();
-                else
-                    message = victim->getPlayer()->getName() + " was killed";
-            }
-            else
-                message = victim->getPlayer()->getName() + " died";
-
-            COUT(0) << message << std::endl;
-            Host::Broadcast(message);
-        }
-
         if (victim && victim->getPlayer())
         {
@@ -197,13 +200,5 @@
                 // Reward killer
                 if (killer)
-                {
-                    std::map<PlayerInfo*, Player>::iterator itKiller = this->players_.find(killer->getPlayer());
-                    if (itKiller != this->players_.end())
-                    {
-                        this->playerScored(itKiller->second);
-                    }
-                    else
-                        COUT(2) << "Warning: Killing Pawn was not in the playerlist" << std::endl;
-                }
+                    this->playerScored(killer->getPlayer());
 
                 ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
@@ -225,7 +220,9 @@
     }
 
-    void Gametype::playerScored(Player& player)
-    {
-        player.frags_++;
+    void Gametype::playerScored(PlayerInfo* player)
+    {
+        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
+        if (it != this->players_.end())
+            it->second.frags_++;
     }
 
@@ -336,6 +333,8 @@
         if (spawnpoint)
         {
+            this->playerPreSpawn(player);
             player->startControl(spawnpoint->spawn());
             this->players_[player].state_ = PlayerState::Alive;
+            this->playerPostSpawn(player);
         }
         else
Index: code/trunk/src/orxonox/objects/gametypes/Gametype.h
===================================================================
--- code/trunk/src/orxonox/objects/gametypes/Gametype.h	(revision 2809)
+++ code/trunk/src/orxonox/objects/gametypes/Gametype.h	(revision 2826)
@@ -84,14 +84,23 @@
             virtual void end();
             virtual void playerEntered(PlayerInfo* player);
-            virtual void playerLeft(PlayerInfo* player);
+            virtual bool playerLeft(PlayerInfo* player);
             virtual void playerSwitched(PlayerInfo* player, Gametype* newgametype);
             virtual void playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype);
-            virtual void playerChangedName(PlayerInfo* player);
+            virtual bool playerChangedName(PlayerInfo* player);
 
-            virtual void playerScored(Player& player);
+            virtual void playerScored(PlayerInfo* player);
+
+            virtual bool allowPawnHit(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDamage(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDeath(Pawn* victim, Pawn* originator = 0);
 
             virtual void pawnKilled(Pawn* victim, Pawn* killer = 0);
             virtual void pawnPreSpawn(Pawn* pawn);
             virtual void pawnPostSpawn(Pawn* pawn);
+            virtual void playerPreSpawn(PlayerInfo* player);
+            virtual void playerPostSpawn(PlayerInfo* player);
+
+            virtual void playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn);
+            virtual void playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn);
 
             inline const std::map<PlayerInfo*, Player>& getPlayers() const
@@ -106,4 +115,9 @@
                 { return this->gtinfo_.startCountdown_; }
 
+            inline void setHUDTemplate(const std::string& name)
+                { this->gtinfo_.hudtemplate_ = name; }
+            inline const std::string& getHUDTemplate() const
+                { return this->gtinfo_.hudtemplate_; }
+
             void addBots(unsigned int amount);
             void killBots(unsigned int amount = 0);
@@ -112,15 +126,12 @@
                 { return this->players_.size(); }
 
-        private:
+        protected:
             virtual SpawnPoint* getBestSpawnPoint(PlayerInfo* player) const;
 
-            void addPlayer(PlayerInfo* player);
-            void removePlayer(PlayerInfo* player);
-
-            void assignDefaultPawnsIfNeeded();
-            void checkStart();
-            void spawnPlayer(PlayerInfo* player);
-            void spawnPlayersIfRequested();
-            void spawnDeadPlayersIfRequested();
+            virtual void assignDefaultPawnsIfNeeded();
+            virtual void checkStart();
+            virtual void spawnPlayer(PlayerInfo* player);
+            virtual void spawnPlayersIfRequested();
+            virtual void spawnDeadPlayersIfRequested();
 
             GametypeInfo gtinfo_;
Index: code/trunk/src/orxonox/objects/gametypes/Pong.cc
===================================================================
--- code/trunk/src/orxonox/objects/gametypes/Pong.cc	(revision 2826)
+++ code/trunk/src/orxonox/objects/gametypes/Pong.cc	(revision 2826)
@@ -0,0 +1,162 @@
+/*
+ *   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 "Pong.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/Executor.h"
+#include "objects/worldentities/Model.h"
+#include "objects/worldentities/PongCenterpoint.h"
+#include "objects/worldentities/PongBall.h"
+#include "objects/worldentities/PongBat.h"
+#include "objects/infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(Pong);
+
+    Pong::Pong(BaseObject* creator) : Deathmatch(creator)
+    {
+        RegisterObject(Pong);
+
+        this->center_ = 0;
+        this->ball_ = 0;
+        this->bat_[0] = 0;
+        this->bat_[1] = 0;
+
+        this->bForceSpawn_ = true;
+
+        this->starttimer_.setTimer(1.0, false, this, createExecutor(createFunctor(&Pong::startBall)));
+        this->starttimer_.stopTimer();
+    }
+
+    void Pong::start()
+    {
+        if (this->center_)
+        {
+            if (!this->ball_)
+            {
+                this->ball_ = new PongBall(this->center_);
+                this->ball_->addTemplate(this->center_->getBalltemplate());
+            }
+
+            this->center_->attach(this->ball_);
+            this->ball_->setPosition(0, 0, 0);
+            this->ball_->setFieldDimension(this->center_->getFieldDimension());
+            this->ball_->setSpeed(0);
+            this->ball_->setBatLength(this->center_->getBatLength());
+
+            if (!this->bat_[0])
+            {
+                this->bat_[0] = new PongBat(this->center_);
+                this->bat_[0]->addTemplate(this->center_->getBattemplate());
+            }
+            if (!this->bat_[1])
+            {
+                this->bat_[1] = new PongBat(this->center_);
+                this->bat_[1]->addTemplate(this->center_->getBattemplate());
+            }
+
+            this->center_->attach(this->bat_[0]);
+            this->center_->attach(this->bat_[1]);
+            this->bat_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
+            this->bat_[1]->setPosition( this->center_->getFieldDimension().x / 2, 0, 0);
+            this->bat_[0]->yaw(Degree(-90));
+            this->bat_[1]->yaw(Degree(90));
+            this->bat_[0]->setSpeed(this->center_->getBatSpeed());
+            this->bat_[1]->setSpeed(this->center_->getBatSpeed());
+            this->bat_[0]->setFieldHeight(this->center_->getFieldDimension().y);
+            this->bat_[1]->setFieldHeight(this->center_->getFieldDimension().y);
+            this->bat_[0]->setLength(this->center_->getBatLength());
+            this->bat_[1]->setLength(this->center_->getBatLength());
+
+            this->ball_->setBats(this->bat_);
+        }
+        else
+        {
+            COUT(1) << "Error: No Centerpoint specified." << std::endl;
+        }
+
+        this->starttimer_.startTimer();
+
+        Deathmatch::start();
+    }
+
+    void Pong::end()
+    {
+        if (this->ball_)
+        {
+            delete this->ball_;
+            this->ball_ = 0;
+        }
+
+        Deathmatch::end();
+    }
+
+    void Pong::spawnPlayer(PlayerInfo* player)
+    {
+        if (!this->bat_[0]->getPlayer())
+        {
+            player->startControl(this->bat_[0]);
+            this->players_[player].state_ = PlayerState::Alive;
+        }
+        else if (!this->bat_[1]->getPlayer())
+        {
+            player->startControl(this->bat_[1]);
+            this->players_[player].state_ = PlayerState::Alive;
+        }
+    }
+
+    void Pong::playerScored(PlayerInfo* player)
+    {
+        Deathmatch::playerScored(player);
+
+        if (this->ball_)
+        {
+            this->ball_->setPosition(Vector3::ZERO);
+            this->ball_->setVelocity(Vector3::ZERO);
+            this->ball_->setSpeed(0);
+        }
+
+        if (this->bat_[0] && this->bat_[1])
+        {
+            this->bat_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
+            this->bat_[1]->setPosition( this->center_->getFieldDimension().x / 2, 0, 0);
+        }
+
+        this->starttimer_.startTimer();
+    }
+
+    void Pong::startBall()
+    {
+        if (this->ball_ && this->center_)
+            this->ball_->setSpeed(this->center_->getBallSpeed());
+    }
+}
Index: code/trunk/src/orxonox/objects/gametypes/Pong.h
===================================================================
--- code/trunk/src/orxonox/objects/gametypes/Pong.h	(revision 2826)
+++ code/trunk/src/orxonox/objects/gametypes/Pong.h	(revision 2826)
@@ -0,0 +1,65 @@
+/*
+ *   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 _Pong_H__
+#define _Pong_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "Deathmatch.h"
+#include "tools/Timer.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Pong : public Deathmatch
+    {
+        public:
+            Pong(BaseObject* creator);
+            virtual ~Pong() {}
+
+            virtual void start();
+            virtual void end();
+
+            virtual void spawnPlayer(PlayerInfo* player);
+
+            virtual void playerScored(PlayerInfo* player);
+
+            void setCenterpoint(PongCenterpoint* center)
+                { this->center_ = center; }
+
+        protected:
+            void startBall();
+
+            PongCenterpoint* center_;
+            PongBall* ball_;
+            PongBat* bat_[2];
+            Timer<Pong> starttimer_;
+    };
+}
+
+#endif /* _Pong_H__ */
Index: code/trunk/src/orxonox/objects/gametypes/TeamDeathmatch.cc
===================================================================
--- code/trunk/src/orxonox/objects/gametypes/TeamDeathmatch.cc	(revision 2826)
+++ code/trunk/src/orxonox/objects/gametypes/TeamDeathmatch.cc	(revision 2826)
@@ -0,0 +1,191 @@
+/*
+ *   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 "TeamDeathmatch.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "objects/Teamcolourable.h"
+#include "objects/worldentities/TeamSpawnPoint.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(TeamDeathmatch);
+
+    TeamDeathmatch::TeamDeathmatch(BaseObject* creator) : Deathmatch(creator)
+    {
+        RegisterObject(TeamDeathmatch);
+
+        this->teams_ = 2;
+
+        this->setConfigValues();
+    }
+
+    void TeamDeathmatch::setConfigValues()
+    {
+        SetConfigValue(teams_, 2);
+
+        static ColourValue colours[] =
+        {
+            ColourValue(1.0, 0.3, 0.3),
+            ColourValue(0.3, 0.3, 1.0),
+            ColourValue(0.3, 1.0, 0.3),
+            ColourValue(1.0, 1.0, 0.0)
+        };
+        static std::vector<ColourValue> defaultcolours(colours, colours + sizeof(colours) / sizeof(ColourValue));
+
+        SetConfigValueVector(teamcolours_, defaultcolours);
+    }
+
+    void TeamDeathmatch::playerEntered(PlayerInfo* player)
+    {
+        Deathmatch::playerEntered(player);
+
+        std::vector<unsigned int> playersperteam(this->teams_, 0);
+
+        for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
+            if (it->second < this->teams_ && it->second >= 0)
+                playersperteam[it->second]++;
+
+        unsigned int minplayers = (unsigned int)-1;
+        size_t minplayersteam = 0;
+        for (size_t i = 0; i < this->teams_; ++i)
+        {
+            if (playersperteam[i] < minplayers)
+            {
+                minplayers = playersperteam[i];
+                minplayersteam = i;
+            }
+        }
+
+        this->teamnumbers_[player] = minplayersteam;
+    }
+
+    bool TeamDeathmatch::playerLeft(PlayerInfo* player)
+    {
+        bool valid_player = Deathmatch::playerLeft(player);
+
+        if (valid_player)
+            this->players_.erase(player);
+
+        return valid_player;
+    }
+
+    bool TeamDeathmatch::allowPawnHit(Pawn* victim, Pawn* originator)
+    {
+        return (!this->pawnsAreInTheSameTeam(victim, originator));
+    }
+
+    bool TeamDeathmatch::allowPawnDamage(Pawn* victim, Pawn* originator)
+    {
+        return (!this->pawnsAreInTheSameTeam(victim, originator));
+    }
+
+    bool TeamDeathmatch::allowPawnDeath(Pawn* victim, Pawn* originator)
+    {
+        return (!this->pawnsAreInTheSameTeam(victim, originator));
+    }
+
+    SpawnPoint* TeamDeathmatch::getBestSpawnPoint(PlayerInfo* player) const
+    {
+        int desiredTeamNr = -1;
+        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
+        if (it_player != this->teamnumbers_.end())
+            desiredTeamNr = it_player->second;
+
+        // Only use spawnpoints of the own team (or non-team-spawnpoints)
+        std::set<SpawnPoint*> teamSpawnPoints = this->spawnpoints_;
+        for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); )
+        {
+            if ((*it)->isA(Class(TeamSpawnPoint)))
+            {
+                TeamSpawnPoint* tsp = dynamic_cast<TeamSpawnPoint*>(*it);
+                if (tsp && tsp->getTeamNumber() != desiredTeamNr)
+                {
+                    teamSpawnPoints.erase(it++);
+                    continue;
+                }
+            }
+
+            ++it;
+        }
+
+        if (teamSpawnPoints.size() > 0)
+        {
+            unsigned int randomspawn = (unsigned int)rnd(teamSpawnPoints.size());
+            unsigned int index = 0;
+            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); ++it)
+            {
+                if (index == randomspawn)
+                    return (*it);
+
+                ++index;
+            }
+        }
+
+        return 0;
+    }
+
+    void TeamDeathmatch::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
+    {
+        if (!player)
+            return;
+
+        // Set the team colour
+        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
+        if (it_player != this->teamnumbers_.end() && it_player->second >= 0 && it_player->second < this->teamcolours_.size())
+        {
+            if (pawn)
+            {
+                std::set<WorldEntity*> pawnAttachments = pawn->getAttachedObjects();
+                for (std::set<WorldEntity*>::iterator it = pawnAttachments.begin(); it != pawnAttachments.end(); ++it)
+                {
+                    if ((*it)->isA(Class(Teamcolourable)))
+                    {
+                        Teamcolourable* tc = dynamic_cast<Teamcolourable*>(*it);
+                        tc->setTeamColour(this->teamcolours_[it_player->second]);
+                    }
+                }
+            }
+        }
+    }
+
+    bool TeamDeathmatch::pawnsAreInTheSameTeam(Pawn* pawn1, Pawn* pawn2)
+    {
+        if (pawn1 && pawn2)
+        {
+            std::map<PlayerInfo*, int>::const_iterator it1 = this->teamnumbers_.find(pawn1->getPlayer());
+            std::map<PlayerInfo*, int>::const_iterator it2 = this->teamnumbers_.find(pawn2->getPlayer());
+
+            if (it1 != this->teamnumbers_.end() && it2 != this->teamnumbers_.end())
+                return (it1->second == it2->second);
+        }
+        return false;
+    }
+}
Index: code/trunk/src/orxonox/objects/gametypes/TeamDeathmatch.h
===================================================================
--- code/trunk/src/orxonox/objects/gametypes/TeamDeathmatch.h	(revision 2826)
+++ code/trunk/src/orxonox/objects/gametypes/TeamDeathmatch.h	(revision 2826)
@@ -0,0 +1,67 @@
+/*
+ *   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 _TeamDeathmatch_H__
+#define _TeamDeathmatch_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <vector>
+
+#include "Deathmatch.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport TeamDeathmatch : public Deathmatch
+    {
+        public:
+            TeamDeathmatch(BaseObject* creator);
+            virtual ~TeamDeathmatch() {}
+
+            void setConfigValues();
+
+            virtual void playerEntered(PlayerInfo* player);
+            virtual bool playerLeft(PlayerInfo* player);
+
+            virtual bool allowPawnHit(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDamage(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDeath(Pawn* victim, Pawn* originator = 0);
+
+            virtual void playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn);
+
+        protected:
+            virtual SpawnPoint* getBestSpawnPoint(PlayerInfo* player) const;
+            bool pawnsAreInTheSameTeam(Pawn* pawn1, Pawn* pawn2);
+
+            std::map<PlayerInfo*, int> teamnumbers_;
+            std::vector<ColourValue> teamcolours_;
+            unsigned int teams_;
+    };
+}
+
+#endif /* _TeamDeathmatch_H__ */
Index: code/trunk/src/orxonox/objects/infos/GametypeInfo.cc
===================================================================
--- code/trunk/src/orxonox/objects/infos/GametypeInfo.cc	(revision 2809)
+++ code/trunk/src/orxonox/objects/infos/GametypeInfo.cc	(revision 2826)
@@ -58,4 +58,5 @@
         registerVariable(this->startCountdown_,         variableDirection::toclient);
         registerVariable(this->bStartCountdownRunning_, variableDirection::toclient);
+        registerVariable(this->hudtemplate_,            variableDirection::toclient);
     }
 }
Index: code/trunk/src/orxonox/objects/infos/GametypeInfo.h
===================================================================
--- code/trunk/src/orxonox/objects/infos/GametypeInfo.h	(revision 2809)
+++ code/trunk/src/orxonox/objects/infos/GametypeInfo.h	(revision 2826)
@@ -56,4 +56,7 @@
                 { return this->startCountdown_; }
 
+            inline const std::string& getHUDTemplate() const
+                { return this->hudtemplate_; }
+
         private:
             bool bStarted_;
@@ -61,4 +64,5 @@
             bool bStartCountdownRunning_;
             float startCountdown_;
+            std::string hudtemplate_;
     };
 }
Index: code/trunk/src/orxonox/objects/infos/HumanPlayer.cc
===================================================================
--- code/trunk/src/orxonox/objects/infos/HumanPlayer.cc	(revision 2809)
+++ code/trunk/src/orxonox/objects/infos/HumanPlayer.cc	(revision 2826)
@@ -53,4 +53,7 @@
         this->defaultController_ = Class(HumanController);
 
+        this->humanHud_ = 0;
+        this->gametypeHud_ = 0;
+
         this->setConfigValues();
         this->registerVariables();
@@ -59,4 +62,12 @@
     HumanPlayer::~HumanPlayer()
     {
+        if (this->BaseObject::isInitialized())
+        {
+            if (this->humanHud_)
+                delete this->humanHud_;
+
+            if (this->gametypeHud_)
+                delete this->gametypeHud_;
+        }
     }
 
@@ -89,5 +100,5 @@
     void HumanPlayer::configvaluecallback_changedHUDTemplate()
     {
-        this->changedController();
+        this->setHumanHUDTemplate(this->hudtemplate_);
     }
 
@@ -111,4 +122,5 @@
 
             this->createController();
+            this->updateHumanHUD();
         }
     }
@@ -146,12 +158,53 @@
     }
 
-    void HumanPlayer::changedController()
-    {
-        if (this->getController())
-        {
-            this->getController()->setHUDTemplate(this->hudtemplate_);
-
-            if (this->getController() && this->getController()->getHUD())
-                this->getController()->getHUD()->setOwner(this->getControllableEntity());
+    void HumanPlayer::changedGametype()
+    {
+        PlayerInfo::changedGametype();
+
+        if (this->isInitialized() && this->isLocalPlayer())
+            if (this->getGametype()->getHUDTemplate() != "")
+                this->setGametypeHUDTemplate(this->getGametype()->getHUDTemplate());
+    }
+
+    void HumanPlayer::changedControllableEntity()
+    {
+        PlayerInfo::changedControllableEntity();
+
+        if (this->humanHud_)
+            this->humanHud_->setOwner(this->getControllableEntity());
+
+        if (this->gametypeHud_)
+            this->gametypeHud_->setOwner(this->getControllableEntity());
+    }
+
+    void HumanPlayer::updateHumanHUD()
+    {
+        if (this->humanHud_)
+        {
+            delete this->humanHud_;
+            this->humanHud_ = 0;
+        }
+
+        if (this->isLocalPlayer() && this->humanHudTemplate_ != "")
+        {
+            this->humanHud_ = new OverlayGroup(this);
+            this->humanHud_->addTemplate(this->humanHudTemplate_);
+            this->humanHud_->setOwner(this->getControllableEntity());
+        }
+    }
+
+    void HumanPlayer::updateGametypeHUD()
+    {
+        if (this->gametypeHud_)
+        {
+            delete this->gametypeHud_;
+            this->gametypeHud_ = 0;
+        }
+
+        if (this->isLocalPlayer() && this->gametypeHudTemplate_ != "")
+        {
+            this->gametypeHud_ = new OverlayGroup(this);
+            this->gametypeHud_->addTemplate(this->gametypeHudTemplate_);
+            this->gametypeHud_->setOwner(this->getControllableEntity());
         }
     }
Index: code/trunk/src/orxonox/objects/infos/HumanPlayer.h
===================================================================
--- code/trunk/src/orxonox/objects/infos/HumanPlayer.h	(revision 2809)
+++ code/trunk/src/orxonox/objects/infos/HumanPlayer.h	(revision 2826)
@@ -51,5 +51,32 @@
             void setClientID(unsigned int clientID);
 
-            virtual void changedController();
+            virtual void changedGametype();
+            virtual void changedControllableEntity();
+
+            inline void setHumanHUDTemplate(const std::string& name)
+            {
+                if (name != this->humanHudTemplate_)
+                {
+                    this->humanHudTemplate_ = name;
+                    this->updateHumanHUD();
+                }
+            }
+            inline const std::string& getHumanHUDTemplate() const
+                { return this->humanHudTemplate_; }
+            inline OverlayGroup* getHumanHUD() const
+                { return this->humanHud_; }
+
+            inline void setGametypeHUDTemplate(const std::string& name)
+            {
+                if (name != this->gametypeHudTemplate_)
+                {
+                    this->gametypeHudTemplate_ = name;
+                    this->updateGametypeHUD();
+                }
+            }
+            inline const std::string& getGametypeHUDTemplate() const
+                { return this->gametypeHudTemplate_; }
+            inline OverlayGroup* getGametypeHUD() const
+                { return this->gametypeHud_; }
 
         protected:
@@ -61,4 +88,7 @@
             void networkcallback_client_initialized();
 
+            void updateHumanHUD();
+            void updateGametypeHUD();
+
             std::string nick_;
             std::string synchronize_nick_;
@@ -66,4 +96,9 @@
             bool server_initialized_;
             bool client_initialized_;
+
+            std::string humanHudTemplate_;
+            OverlayGroup* humanHud_;
+            std::string gametypeHudTemplate_;
+            OverlayGroup* gametypeHud_;
     };
 }
Index: code/trunk/src/orxonox/objects/infos/PlayerInfo.cc
===================================================================
--- code/trunk/src/orxonox/objects/infos/PlayerInfo.cc	(revision 2809)
+++ code/trunk/src/orxonox/objects/infos/PlayerInfo.cc	(revision 2826)
@@ -141,4 +141,6 @@
         if (this->controller_)
             this->controller_->setControllableEntity(entity);
+
+        this->changedControllableEntity();
     }
 
@@ -155,4 +157,6 @@
             if (callback)
                 entity->removePlayer();
+
+            this->changedControllableEntity();
         }
     }
Index: code/trunk/src/orxonox/objects/infos/PlayerInfo.h
===================================================================
--- code/trunk/src/orxonox/objects/infos/PlayerInfo.h	(revision 2809)
+++ code/trunk/src/orxonox/objects/infos/PlayerInfo.h	(revision 2826)
@@ -49,4 +49,7 @@
             virtual void changedGametype();
 
+            virtual void changedController() {}
+            virtual void changedControllableEntity() {}
+
             inline bool isHumanPlayer() const
                 { return this->bHumanPlayer_; }
@@ -73,5 +76,4 @@
             inline Controller* getController() const
                 { return this->controller_; }
-            virtual void changedController() {}
 
         protected:
Index: code/trunk/src/orxonox/objects/worldentities/Billboard.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Billboard.h	(revision 2809)
+++ code/trunk/src/orxonox/objects/worldentities/Billboard.h	(revision 2826)
@@ -34,8 +34,9 @@
 #include "util/Math.h"
 #include "tools/BillboardSet.h"
+#include "objects/Teamcolourable.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport Billboard : public StaticEntity
+    class _OrxonoxExport Billboard : public StaticEntity, public Teamcolourable
     {
         public:
@@ -61,4 +62,7 @@
                 { return this->colour_; }
 
+            virtual void setTeamColour(const ColourValue& colour)
+                { this->setColour(colour); }
+
         protected:
             inline BillboardSet& getBillboardSet()
Index: code/trunk/src/orxonox/objects/worldentities/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/CMakeLists.txt	(revision 2809)
+++ code/trunk/src/orxonox/objects/worldentities/CMakeLists.txt	(revision 2826)
@@ -19,4 +19,8 @@
   Planet.cc
   SpawnPoint.cc
+  TeamSpawnPoint.cc
+  PongCenterpoint.cc
+  PongBall.cc
+  PongBat.cc
 )
 
Index: code/trunk/src/orxonox/objects/worldentities/CameraPosition.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/CameraPosition.cc	(revision 2809)
+++ code/trunk/src/orxonox/objects/worldentities/CameraPosition.cc	(revision 2826)
@@ -44,4 +44,5 @@
         this->bDrag_ = false;
         this->bAllowMouseLook_ = false;
+        this->bAbsolute_ = false;
 
         this->setObjectMode(0x0);
@@ -58,4 +59,5 @@
         XMLPortParam(CameraPosition, "drag", setDrag, getDrag, xmlelement, mode).defaultValues(false);
         XMLPortParam(CameraPosition, "mouselook", setAllowMouseLook, getAllowMouseLook, xmlelement, mode).defaultValues(false);
+        XMLPortParam(CameraPosition, "absolute", setIsAbsolute, getIsAbsolute, xmlelement, mode).defaultValues(false);
     }
 
Index: code/trunk/src/orxonox/objects/worldentities/CameraPosition.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/CameraPosition.h	(revision 2809)
+++ code/trunk/src/orxonox/objects/worldentities/CameraPosition.h	(revision 2826)
@@ -54,4 +54,9 @@
                 { return this->bAllowMouseLook_; }
 
+            inline void setIsAbsolute(bool bAbsolute)
+                { this->bAbsolute_ = bAbsolute; }
+            inline bool getIsAbsolute() const
+                { return this->bAbsolute_; }
+
             void attachCamera(Camera* camera);
 
@@ -59,4 +64,5 @@
             bool bDrag_;
             bool bAllowMouseLook_;
+            bool bAbsolute_;
     };
 }
Index: code/trunk/src/orxonox/objects/worldentities/ControllableEntity.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/ControllableEntity.cc	(revision 2809)
+++ code/trunk/src/orxonox/objects/worldentities/ControllableEntity.cc	(revision 2826)
@@ -144,8 +144,17 @@
     void ControllableEntity::addCameraPosition(CameraPosition* position)
     {
-        if (position->getAllowMouseLook())
-            position->attachToNode(this->cameraPositionRootNode_);
+        if (!position->getIsAbsolute())
+        {
+            if (position->getAllowMouseLook())
+                position->attachToNode(this->cameraPositionRootNode_);
+            else
+                this->attach(position);
+        }
         else
-            this->attach(position);
+        {
+            WorldEntity* parent = this->getParent();
+            if (parent)
+                parent->attach(position);
+        }
         this->cameraPositions_.push_back(position);
     }
Index: code/trunk/src/orxonox/objects/worldentities/Light.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/Light.h	(revision 2809)
+++ code/trunk/src/orxonox/objects/worldentities/Light.h	(revision 2826)
@@ -37,8 +37,9 @@
 
 #include "util/Math.h"
+#include "objects/Teamcolourable.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport Light : public StaticEntity
+    class _OrxonoxExport Light : public StaticEntity, public Teamcolourable
     {
         public:
@@ -68,4 +69,7 @@
             inline const ColourValue& getSpecularColour() const
                 { return this->specular_; }
+
+            virtual void setTeamColour(const ColourValue& colour)
+                { this->setDiffuseColour(colour); this->setSpecularColour(colour); }
 
             /**
Index: code/trunk/src/orxonox/objects/worldentities/PongBall.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/PongBall.cc	(revision 2826)
+++ code/trunk/src/orxonox/objects/worldentities/PongBall.cc	(revision 2826)
@@ -0,0 +1,124 @@
+/*
+ *   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 "PongBall.h"
+
+#include "core/CoreIncludes.h"
+#include "objects/worldentities/PongBat.h"
+#include "objects/gametypes/Gametype.h"
+
+namespace orxonox
+{
+    CreateFactory(PongBall);
+
+    PongBall::PongBall(BaseObject* creator) : MovableEntity(creator)
+    {
+        RegisterObject(PongBall);
+
+        this->speed_ = 0;
+        this->bat_ = 0;
+    }
+
+    void PongBall::tick(float dt)
+    {
+        SUPER(PongBall, tick, dt);
+
+        if (Core::isMaster())
+        {
+            Vector3 position = this->getPosition();
+            Vector3 velocity = this->getVelocity();
+
+            if (position.z > this->fieldHeight_ / 2 || position.z < -this->fieldHeight_ / 2)
+            {
+                velocity.z = -velocity.z;
+
+                if (position.z > this->fieldHeight_ / 2)
+                    position.z = this->fieldHeight_ / 2;
+                if (position.z < -this->fieldHeight_ / 2)
+                    position.z = -this->fieldHeight_ / 2;
+            }
+
+            if (position.x > this->fieldWidth_ / 2 || position.x < -this->fieldWidth_ / 2)
+            {
+                velocity.x = -velocity.x;
+                float distance = 0;
+
+                if (position.x > this->fieldWidth_ / 2)
+                {
+                    position.x = this->fieldWidth_ / 2;
+                    if (this->bat_ && this->bat_[1])
+                    {
+                        distance = (position.z - this->bat_[1]->getPosition().z) / (this->fieldHeight_ * this->batlength_ / 2);
+                        if (this->getGametype() && this->bat_[0] && fabs(distance) > 1)
+                        {
+                            this->getGametype()->playerScored(this->bat_[0]->getPlayer());
+                            return;
+                        }
+                    }
+                }
+                if (position.x < -this->fieldWidth_ / 2)
+                {
+                    position.x = -this->fieldWidth_ / 2;
+                    if (this->bat_ && this->bat_[0])
+                    {
+                        distance = (position.z - this->bat_[0]->getPosition().z) / (this->fieldHeight_ * this->batlength_ / 2);
+                        if (this->getGametype() && this->bat_[1] && fabs(distance) > 1)
+                        {
+                            this->getGametype()->playerScored(this->bat_[1]->getPlayer());
+                            return;
+                        }
+                    }
+                }
+
+                velocity.z = distance * distance * sgn(distance) * 1.5 * this->speed_;
+            }
+
+            if (velocity != this->getVelocity())
+                this->setVelocity(velocity);
+            if (position != this->getPosition())
+                this->setPosition(position);
+        }
+    }
+
+    void PongBall::setSpeed(float speed)
+    {
+        if (speed != this->speed_)
+        {
+            this->speed_ = speed;
+
+            Vector3 velocity = this->getVelocity();
+            if (velocity.x != 0)
+                velocity.x = sgn(velocity.x) * this->speed_;
+            else
+                velocity.x = this->speed_ * sgn(rnd(-1,1));
+
+            this->setVelocity(velocity);
+        }
+    }
+}
Index: code/trunk/src/orxonox/objects/worldentities/PongBall.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/PongBall.h	(revision 2826)
+++ code/trunk/src/orxonox/objects/worldentities/PongBall.h	(revision 2826)
@@ -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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PongBall_H__
+#define _PongBall_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "objects/worldentities/MovableEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport PongBall : public MovableEntity
+    {
+        public:
+            PongBall(BaseObject* creator);
+            virtual ~PongBall() {}
+
+            virtual void tick(float dt);
+
+            void setFieldDimension(float width, float height)
+                { this->fieldWidth_ = width; this->fieldHeight_ = height; }
+            void setFieldDimension(const Vector2& dimension)
+                { this->setFieldDimension(dimension.x, dimension.y); }
+
+            void setSpeed(float speed);
+            float getSpeed() const
+                { return this->speed_; }
+
+            void setBatLength(float batlength)
+                { this->batlength_ = batlength; }
+            float getBatLength() const
+                { return this->batlength_; }
+
+            void setBats(PongBat** bats)
+                { this->bat_ = bats; }
+
+        private:
+            float fieldWidth_;
+            float fieldHeight_;
+            float speed_;
+            float batlength_;
+            PongBat** bat_;
+    };
+}
+
+#endif /* _PongBall_H__ */
Index: code/trunk/src/orxonox/objects/worldentities/PongBat.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/PongBat.cc	(revision 2826)
+++ code/trunk/src/orxonox/objects/worldentities/PongBat.cc	(revision 2826)
@@ -0,0 +1,100 @@
+/*
+ *   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 "PongBat.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(PongBat);
+
+    PongBat::PongBat(BaseObject* creator) : ControllableEntity(creator)
+    {
+        RegisterObject(PongBat);
+
+        this->movement_ = 0;
+        this->bMoveLocal_ = false;
+        this->speed_ = 60;
+        this->length_ = 0.25;
+        this->fieldHeight_ = 100;
+
+        this->registerVariables();
+    }
+
+    void PongBat::registerVariables()
+    {
+        registerVariable(this->speed_);
+        registerVariable(this->speed_);
+        registerVariable(this->speed_);
+    }
+
+    void PongBat::tick(float dt)
+    {
+        if (this->hasLocalController())
+        {
+            this->movement_ = clamp(this->movement_, -1.0f, 1.0f) * this->speed_;
+
+            if (this->bMoveLocal_)
+                this->setVelocity(this->getOrientation() * Vector3(this->movement_, 0, 0));
+            else
+                this->setVelocity(0, 0, this->movement_);
+
+            this->movement_ = 0;
+        }
+
+        SUPER(PongBat, tick, dt);
+
+        if (this->hasLocalController())
+        {
+            Vector3 position = this->getPosition();
+
+            if (position.z > this->fieldHeight_ / 2 - this->fieldHeight_ * this->length_ / 2)
+                position.z = this->fieldHeight_ / 2 - this->fieldHeight_ * this->length_ / 2;
+            if (position.z < -this->fieldHeight_ / 2 + this->fieldHeight_ * this->length_ / 2)
+                position.z = -this->fieldHeight_ / 2 + this->fieldHeight_ * this->length_ / 2;
+
+            if (position != this->getPosition())
+                this->setPosition(position);
+        }
+    }
+
+    void PongBat::moveFrontBack(const Vector2& value)
+    {
+        this->bMoveLocal_ = false;
+        this->movement_ -= value.x;
+    }
+
+    void PongBat::moveRightLeft(const Vector2& value)
+    {
+        this->bMoveLocal_ = true;
+        this->movement_ = value.x;
+    }
+}
Index: code/trunk/src/orxonox/objects/worldentities/PongBat.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/PongBat.h	(revision 2826)
+++ code/trunk/src/orxonox/objects/worldentities/PongBat.h	(revision 2826)
@@ -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:
+ *      ...
+ *
+ */
+
+#ifndef _PongBat_H__
+#define _PongBat_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "objects/worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport PongBat : public ControllableEntity
+    {
+        public:
+            PongBat(BaseObject* creator);
+            virtual ~PongBat() {}
+
+            void registerVariables();
+            virtual void tick(float dt);
+
+            virtual void moveFrontBack(const Vector2& value);
+            virtual void moveRightLeft(const Vector2& value);
+
+            void setSpeed(float speed)
+                { this->speed_ = speed; }
+            float getSpeed() const
+                { return this->speed_; }
+
+            void setFieldHeight(float height)
+                { this->fieldHeight_ = height; }
+            float getFieldHeight() const
+                { return this->fieldHeight_; }
+
+            void setLength(float length)
+                { this->length_ = length; }
+            float getLength() const
+                { return this->length_; }
+
+        private:
+            float movement_;
+            bool bMoveLocal_;
+            float speed_;
+            float length_;
+            float fieldHeight_;
+    };
+}
+
+#endif /* _PongBat_H__ */
Index: code/trunk/src/orxonox/objects/worldentities/PongCenterpoint.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/PongCenterpoint.cc	(revision 2826)
+++ code/trunk/src/orxonox/objects/worldentities/PongCenterpoint.cc	(revision 2826)
@@ -0,0 +1,80 @@
+/*
+ *   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 "PongCenterpoint.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "objects/gametypes/Pong.h"
+
+namespace orxonox
+{
+    CreateFactory(PongCenterpoint);
+
+    PongCenterpoint::PongCenterpoint(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(PongCenterpoint);
+
+        this->width_ = 200;
+        this->height_ = 120;
+        this->ballspeed_ = 100;
+        this->batspeed_ = 60;
+        this->batlength_ = 0.25;
+
+        this->checkGametype();
+    }
+
+    void PongCenterpoint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(PongCenterpoint, XMLPort, xmlelement, mode);
+
+        XMLPortParam(PongCenterpoint, "dimension", setFieldDimension, getFieldDimension, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "balltemplate", setBalltemplate, getBalltemplate, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "battemplate", setBattemplate, getBattemplate, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "ballspeed", setBallSpeed, getBallSpeed, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "batspeed", setBatSpeed, getBatSpeed, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "batlength", setBatLength, getBatLength, xmlelement, mode);
+    }
+
+    void PongCenterpoint::changedGametype()
+    {
+        SUPER(PongCenterpoint, changedGametype);
+
+        this->checkGametype();
+    }
+
+    void PongCenterpoint::checkGametype()
+    {
+        if (this->getGametype() && this->getGametype()->isA(Class(Pong)))
+        {
+            Pong* pong_gametype = dynamic_cast<Pong*>(this->getGametype());
+            pong_gametype->setCenterpoint(this);
+        }
+    }
+}
Index: code/trunk/src/orxonox/objects/worldentities/PongCenterpoint.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/PongCenterpoint.h	(revision 2826)
+++ code/trunk/src/orxonox/objects/worldentities/PongCenterpoint.h	(revision 2826)
@@ -0,0 +1,93 @@
+/*
+ *   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 _PongCenterpoint_H__
+#define _PongCenterpoint_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "objects/worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport PongCenterpoint : public StaticEntity
+    {
+        public:
+            PongCenterpoint(BaseObject* creator);
+            virtual ~PongCenterpoint() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            virtual void changedGametype();
+
+            void setBalltemplate(const std::string& balltemplate)
+                { this->balltemplate_ = balltemplate; }
+            const std::string& getBalltemplate() const
+                { return this->balltemplate_; }
+
+            void setBattemplate(const std::string& battemplate)
+                { this->battemplate_ = battemplate; }
+            const std::string& getBattemplate() const
+                { return this->battemplate_; }
+
+            void setFieldDimension(const Vector2& dimension)
+                { this->width_ = dimension.x; this->height_ = dimension.y; }
+            Vector2 getFieldDimension() const
+                { return Vector2(this->width_, this->height_); }
+
+            void setBallSpeed(float ballspeed)
+                { this->ballspeed_ = ballspeed; }
+            float getBallSpeed() const
+                { return this->ballspeed_; }
+
+            void setBatSpeed(float batspeed)
+                { this->batspeed_ = batspeed; }
+            float getBatSpeed() const
+                { return this->batspeed_; }
+
+            void setBatLength(float batlength)
+                { this->batlength_ = batlength; }
+            float getBatLength() const
+                { return this->batlength_; }
+
+        private:
+            void checkGametype();
+
+            std::string balltemplate_;
+            std::string battemplate_;
+
+            float ballspeed_;
+            float batspeed_;
+            float batlength_;
+
+            float width_;
+            float height_;
+    };
+}
+
+#endif /* _PongCenterpoint_H__ */
Index: code/trunk/src/orxonox/objects/worldentities/TeamSpawnPoint.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/TeamSpawnPoint.cc	(revision 2826)
+++ code/trunk/src/orxonox/objects/worldentities/TeamSpawnPoint.cc	(revision 2826)
@@ -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:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "TeamSpawnPoint.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(TeamSpawnPoint);
+
+    TeamSpawnPoint::TeamSpawnPoint(BaseObject* creator) : SpawnPoint(creator)
+    {
+        RegisterObject(TeamSpawnPoint);
+
+        this->teamNumber_ = 0;
+    }
+
+    void TeamSpawnPoint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(TeamSpawnPoint, XMLPort, xmlelement, mode);
+
+        XMLPortParam(TeamSpawnPoint, "team", setTeamNumber, getTeamNumber, xmlelement, mode).defaultValues(0);
+    }
+}
Index: code/trunk/src/orxonox/objects/worldentities/TeamSpawnPoint.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/TeamSpawnPoint.h	(revision 2826)
+++ code/trunk/src/orxonox/objects/worldentities/TeamSpawnPoint.h	(revision 2826)
@@ -0,0 +1,56 @@
+/*
+ *   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 _TeamSpawnPoint_H__
+#define _TeamSpawnPoint_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "SpawnPoint.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport TeamSpawnPoint : public SpawnPoint
+    {
+        public:
+            TeamSpawnPoint(BaseObject* creator);
+            virtual ~TeamSpawnPoint() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void setTeamNumber(unsigned int team)
+                { this->teamNumber_ = team; }
+            unsigned int getTeamNumber() const
+                { return this->teamNumber_; }
+
+        private:
+            unsigned int teamNumber_;
+    };
+}
+
+#endif /* _TeamSpawnPoint_H__ */
Index: code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.cc
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.cc	(revision 2809)
+++ code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.cc	(revision 2826)
@@ -133,4 +133,20 @@
     }
 
+    void Pawn::setPlayer(PlayerInfo* player)
+    {
+        ControllableEntity::setPlayer(player);
+
+        if (this->getGametype())
+            this->getGametype()->playerStartsControllingPawn(player, this);
+    }
+
+    void Pawn::removePlayer()
+    {
+        if (this->getGametype())
+            this->getGametype()->playerStopsControllingPawn(this->getPlayer(), this);
+
+        ControllableEntity::removePlayer();
+    }
+
     void Pawn::setHealth(float health)
     {
@@ -140,16 +156,22 @@
     void Pawn::damage(float damage, Pawn* originator)
     {
-        this->setHealth(this->health_ - damage);
-        this->lastHitOriginator_ = originator;
-
-        // play damage effect
+        if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
+        {
+            this->setHealth(this->health_ - damage);
+            this->lastHitOriginator_ = originator;
+
+            // play damage effect
+        }
     }
 
     void Pawn::hit(Pawn* originator, const Vector3& force, float damage)
     {
-        this->damage(damage, originator);
-        this->setVelocity(this->getVelocity() + force);
-
-        // play hit effect
+        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator))
+        {
+            this->damage(damage, originator);
+            this->setVelocity(this->getVelocity() + force);
+
+            // play hit effect
+        }
     }
 
@@ -176,17 +198,22 @@
     void Pawn::death()
     {
-        // Set bAlive_ to false and wait for PawnManager to do the destruction
-        this->bAlive_ = false;
-
-        this->setDestroyWhenPlayerLeft(false);
-
-        if (this->getGametype())
-            this->getGametype()->pawnKilled(this, this->lastHitOriginator_);
-
-        if (this->getPlayer())
-            this->getPlayer()->stopControl(this);
-
-        if (Core::isMaster())
-            this->deatheffect();
+        if (this->getGametype() && this->getGametype()->allowPawnDeath(this, this->lastHitOriginator_))
+        {
+            // Set bAlive_ to false and wait for PawnManager to do the destruction
+            this->bAlive_ = false;
+
+            this->setDestroyWhenPlayerLeft(false);
+
+            if (this->getGametype())
+                this->getGametype()->pawnKilled(this, this->lastHitOriginator_);
+
+            if (this->getPlayer())
+                this->getPlayer()->stopControl(this);
+
+            if (Core::isMaster())
+                this->deatheffect();
+        }
+        else
+            this->setHealth(1);
     }
 
Index: code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.h
===================================================================
--- code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.h	(revision 2809)
+++ code/trunk/src/orxonox/objects/worldentities/pawns/Pawn.h	(revision 2826)
@@ -47,4 +47,7 @@
             virtual void tick(float dt);
             void registerVariables();
+
+            virtual void setPlayer(PlayerInfo* player);
+            virtual void removePlayer();
 
             inline bool isAlive() const
