Index: code/trunk/src/orxonox/gametypes/Asteroids.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/Asteroids.cc	(revision 5781)
+++ code/trunk/src/orxonox/gametypes/Asteroids.cc	(revision 5929)
@@ -54,5 +54,5 @@
         if (this->time_ < 0 && !this->hasEnded() && this->timerIsActive_)
         {
-            this->gtinfo_.sendAnnounceMessage("Time's up - you have lost the match!");
+            this->gtinfo_->sendAnnounceMessage("Time's up - you have lost the match!");
             this->end();
         }
@@ -63,5 +63,5 @@
         if (victim && victim->getPlayer())
         {
-            this->gtinfo_.sendAnnounceMessage("You're dead - you have lost the match!");
+            this->gtinfo_->sendAnnounceMessage("You're dead - you have lost the match!");
             this->end();
         }
Index: code/trunk/src/orxonox/gametypes/Gametype.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/Gametype.cc	(revision 5781)
+++ code/trunk/src/orxonox/gametypes/Gametype.cc	(revision 5929)
@@ -33,4 +33,5 @@
 #include "core/ConfigValueIncludes.h"
 #include "core/GameMode.h"
+#include "core/ConsoleCommand.h"
 
 #include "infos/PlayerInfo.h"
@@ -47,9 +48,11 @@
     CreateUnloadableFactory(Gametype);
 
-    Gametype::Gametype(BaseObject* creator) : BaseObject(creator), gtinfo_(creator)
+    Gametype::Gametype(BaseObject* creator) : BaseObject(creator)
     {
         RegisterObject(Gametype);
-
-        this->setGametype(this);
+        
+        this->gtinfo_ = new GametypeInfo(creator);
+
+        this->setGametype(SmartPtr<Gametype>(this, false));
 
         this->defaultControllableEntity_ = Class(Spectator);
@@ -76,4 +79,23 @@
         else
             this->scoreboard_ = 0;
+        
+        /* HACK HACK HACK */
+        this->hackAddBots_ = createConsoleCommand( createFunctor(&Gametype::addBots, this), "hackAddBots");
+        this->hackKillBots_ = createConsoleCommand( createFunctor(&Gametype::killBots, this), "hackKillBots");
+        CommandExecutor::addConsoleCommandShortcut( this->hackAddBots_ );
+        CommandExecutor::addConsoleCommandShortcut( this->hackKillBots_ );
+        /* HACK HACK HACK */
+    }
+    
+    Gametype::~Gametype()
+    {
+        if (this->isInitialized())
+        {
+            this->gtinfo_->destroy();
+            if( this->hackAddBots_ )
+                delete this->hackAddBots_;
+            if( this->hackKillBots_ )
+                delete this->hackKillBots_;
+        }
     }
 
@@ -100,10 +122,10 @@
         }
 
-        if (this->gtinfo_.bStartCountdownRunning_ && !this->gtinfo_.bStarted_)
-            this->gtinfo_.startCountdown_ -= dt;
-
-        if (!this->gtinfo_.bStarted_)
+        if (this->gtinfo_->bStartCountdownRunning_ && !this->gtinfo_->bStarted_)
+            this->gtinfo_->startCountdown_ -= dt;
+
+        if (!this->gtinfo_->bStarted_)
             this->checkStart();
-        else if (!this->gtinfo_.bEnded_)
+        else if (!this->gtinfo_->bEnded_)
             this->spawnDeadPlayersIfRequested();
 
@@ -115,5 +137,5 @@
         this->addBots(this->numberOfBots_);
 
-        this->gtinfo_.bStarted_ = true;
+        this->gtinfo_->bStarted_ = true;
 
         this->spawnPlayersIfRequested();
@@ -122,5 +144,5 @@
     void Gametype::end()
     {
-        this->gtinfo_.bEnded_ = true;
+        this->gtinfo_->bEnded_ = true;
 
         for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
@@ -130,5 +152,5 @@
                 ControllableEntity* oldentity = it->first->getControllableEntity();
 
-                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(oldentity->getCreator());
+                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(oldentity);
                 if (oldentity->getCamera())
                 {
@@ -243,7 +265,7 @@
 
                         if (killer->getPlayer()->getClientID() != CLIENTID_UNKNOWN)
-                            this->gtinfo_.sendKillMessage("You killed " + victim->getPlayer()->getName(), killer->getPlayer()->getClientID());
+                            this->gtinfo_->sendKillMessage("You killed " + victim->getPlayer()->getName(), killer->getPlayer()->getClientID());
                         if (victim->getPlayer()->getClientID() != CLIENTID_UNKNOWN)
-                            this->gtinfo_.sendDeathMessage("You were killed by " + killer->getPlayer()->getName(), victim->getPlayer()->getClientID());
+                            this->gtinfo_->sendDeathMessage("You were killed by " + killer->getPlayer()->getName(), victim->getPlayer()->getClientID());
                     }
                 }
@@ -308,5 +330,5 @@
                 it->second.state_ = PlayerState::Dead;
 
-                if (!it->first->isReadyToSpawn() || !this->gtinfo_.bStarted_)
+                if (!it->first->isReadyToSpawn() || !this->gtinfo_->bStarted_)
                 {
                     this->spawnPlayerAsDefaultPawn(it->first);
@@ -319,12 +341,12 @@
     void Gametype::checkStart()
     {
-        if (!this->gtinfo_.bStarted_)
-        {
-            if (this->gtinfo_.bStartCountdownRunning_)
-            {
-                if (this->gtinfo_.startCountdown_ <= 0)
-                {
-                    this->gtinfo_.bStartCountdownRunning_ = false;
-                    this->gtinfo_.startCountdown_ = 0;
+        if (!this->gtinfo_->bStarted_)
+        {
+            if (this->gtinfo_->bStartCountdownRunning_)
+            {
+                if (this->gtinfo_->startCountdown_ <= 0)
+                {
+                    this->gtinfo_->bStartCountdownRunning_ = false;
+                    this->gtinfo_->startCountdown_ = 0;
                     this->start();
                 }
@@ -349,6 +371,6 @@
                     if (allplayersready && hashumanplayers)
                     {
-                        this->gtinfo_.startCountdown_ = this->initialStartCountdown_;
-                        this->gtinfo_.bStartCountdownRunning_ = true;
+                        this->gtinfo_->startCountdown_ = this->initialStartCountdown_;
+                        this->gtinfo_->bStartCountdownRunning_ = true;
                     }
                 }
@@ -419,7 +441,9 @@
             if (it->getGametype() == this)
             {
-                delete (*(it++));
+                (it++)->destroy();
                 ++i;
             }
+            else
+                ++it;
         }
     }
Index: code/trunk/src/orxonox/gametypes/Gametype.h
===================================================================
--- code/trunk/src/orxonox/gametypes/Gametype.h	(revision 5781)
+++ code/trunk/src/orxonox/gametypes/Gametype.h	(revision 5929)
@@ -37,5 +37,5 @@
 
 #include "core/BaseObject.h"
-#include "core/Identifier.h"
+#include "core/SubclassIdentifier.h"
 #include "tools/interfaces/Tickable.h"
 #include "infos/GametypeInfo.h"
@@ -68,5 +68,5 @@
         public:
             Gametype(BaseObject* creator);
-            virtual ~Gametype() {}
+            virtual ~Gametype();
 
             void setConfigValues();
@@ -75,10 +75,10 @@
 
             inline const GametypeInfo* getGametypeInfo() const
-                { return &this->gtinfo_; }
+                { return this->gtinfo_; }
 
             inline bool hasStarted() const
-                { return this->gtinfo_.bStarted_; }
+                { return this->gtinfo_->bStarted_; }
             inline bool hasEnded() const
-                { return this->gtinfo_.bEnded_; }
+                { return this->gtinfo_->bEnded_; }
 
             virtual void start();
@@ -114,12 +114,12 @@
 
             inline bool isStartCountdownRunning() const
-                { return this->gtinfo_.bStartCountdownRunning_; }
+                { return this->gtinfo_->bStartCountdownRunning_; }
             inline float getStartCountdown() const
-                { return this->gtinfo_.startCountdown_; }
+                { return this->gtinfo_->startCountdown_; }
 
             inline void setHUDTemplate(const std::string& name)
-                { this->gtinfo_.hudtemplate_ = name; }
+                { this->gtinfo_->hudtemplate_ = name; }
             inline const std::string& getHUDTemplate() const
-                { return this->gtinfo_.hudtemplate_; }
+                { return this->gtinfo_->hudtemplate_; }
 
             void addBots(unsigned int amount);
@@ -163,5 +163,5 @@
             virtual void spawnDeadPlayersIfRequested();
 
-            GametypeInfo gtinfo_;
+            SmartPtr<GametypeInfo> gtinfo_;
 
             bool bAutoStart_;
@@ -184,4 +184,9 @@
             // Config Values
             std::string scoreboardTemplate_;
+            
+            /* HACK HACK HACK */
+            ConsoleCommand* hackAddBots_;
+            ConsoleCommand* hackKillBots_;
+            /* HACK HACK HACK */
     };
 }
Index: code/trunk/src/orxonox/gametypes/TeamBaseMatch.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/TeamBaseMatch.cc	(revision 5781)
+++ code/trunk/src/orxonox/gametypes/TeamBaseMatch.cc	(revision 5929)
@@ -42,6 +42,6 @@
         RegisterObject(TeamBaseMatch);
 
-        this->scoreTimer_.setTimer(10, true, this, createExecutor(createFunctor(&TeamBaseMatch::winPoints)));
-        this->outputTimer_.setTimer(10, true, this, createExecutor(createFunctor(&TeamBaseMatch::showPoints)));
+        this->scoreTimer_.setTimer(10, true, createExecutor(createFunctor(&TeamBaseMatch::winPoints, this)));
+        this->outputTimer_.setTimer(10, true, createExecutor(createFunctor(&TeamBaseMatch::showPoints, this)));
 
         this->pointsTeam1_ = 0;
@@ -67,10 +67,10 @@
                 {
                     base->setState(BaseState::ControlTeam1);
-                    this->gtinfo_.sendAnnounceMessage("The red team captured a base");
+                    this->gtinfo_->sendAnnounceMessage("The red team captured a base");
                 }
                 if (teamnr == 1)
                 {
                     base->setState(BaseState::ControlTeam2);
-                    this->gtinfo_.sendAnnounceMessage("The blue team captured a base");
+                    this->gtinfo_->sendAnnounceMessage("The blue team captured a base");
                 }
             }
@@ -194,7 +194,7 @@
 
                 if (it->second == winningteam)
-                    this->gtinfo_.sendAnnounceMessage("You have won the match!", it->first->getClientID());
+                    this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
                 else
-                    this->gtinfo_.sendAnnounceMessage("You have lost the match!", it->first->getClientID());
+                    this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
             }
 
Index: code/trunk/src/orxonox/gametypes/TeamBaseMatch.h
===================================================================
--- code/trunk/src/orxonox/gametypes/TeamBaseMatch.h	(revision 5781)
+++ code/trunk/src/orxonox/gametypes/TeamBaseMatch.h	(revision 5929)
@@ -65,6 +65,6 @@
 
             std::set<TeamBaseMatchBase*> bases_;
-            Timer<TeamBaseMatch> scoreTimer_;
-            Timer<TeamBaseMatch> outputTimer_;
+            Timer scoreTimer_;
+            Timer outputTimer_;
 
             //points for each team
Index: code/trunk/src/orxonox/gametypes/TeamDeathmatch.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/TeamDeathmatch.cc	(revision 5781)
+++ code/trunk/src/orxonox/gametypes/TeamDeathmatch.cc	(revision 5929)
@@ -93,5 +93,5 @@
 
         if (valid_player)
-            this->players_.erase(player);
+            this->teamnumbers_.erase(player);
 
         return valid_player;
@@ -100,15 +100,15 @@
     bool TeamDeathmatch::allowPawnHit(Pawn* victim, Pawn* originator)
     {
-        return (!this->pawnsAreInTheSameTeam(victim, originator));
+        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
     }
 
     bool TeamDeathmatch::allowPawnDamage(Pawn* victim, Pawn* originator)
     {
-        return (!this->pawnsAreInTheSameTeam(victim, originator));
+        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
     }
 
     bool TeamDeathmatch::allowPawnDeath(Pawn* victim, Pawn* originator)
     {
-        return (!this->pawnsAreInTheSameTeam(victim, originator));
+        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
     }
 
Index: code/trunk/src/orxonox/gametypes/UnderAttack.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/UnderAttack.cc	(revision 5781)
+++ code/trunk/src/orxonox/gametypes/UnderAttack.cc	(revision 5929)
@@ -46,4 +46,5 @@
         this->teams_ = 2;
         this->destroyer_ = 0;
+        this->destroyer_.setCallback(createFunctor(&UnderAttack::killedDestroyer, this));
         this->gameEnded_ = false;
 
@@ -65,24 +66,21 @@
 
 
-    void UnderAttack::destroyedPawn(Pawn* pawn)
+    void UnderAttack::killedDestroyer()
     {
-        if (pawn == this->destroyer_)
+        this->end(); //end gametype
+        std::string message = "Ship destroyed! Team 0 has won!";
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+        this->gameEnded_ = true;
+
+        for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
         {
-            this->end(); //end gametype
-            std::string message = "Ship destroyed! Team 0 has won!";
-            COUT(0) << message << std::endl;
-            Host::Broadcast(message);
-            this->gameEnded_ = true;
+            if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                continue;
 
-            for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
-            {
-                if (it->first->getClientID() == CLIENTID_UNKNOWN)
-                    continue;
-
-                if (it->second == 0)
-                    this->gtinfo_.sendAnnounceMessage("You have won the match!", it->first->getClientID());
-                else
-                    this->gtinfo_.sendAnnounceMessage("You have lost the match!", it->first->getClientID());
-            }
+            if (it->second == 0)
+                this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
+            else
+                this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
         }
     }
@@ -164,7 +162,7 @@
 
                     if (it->second == 1)
-                        this->gtinfo_.sendAnnounceMessage("You have won the match!", it->first->getClientID());
+                        this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
                     else
-                        this->gtinfo_.sendAnnounceMessage("You have lost the match!", it->first->getClientID());
+                        this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
                 }
             }
@@ -178,5 +176,5 @@
                 Host::Broadcast(message);
 */
-                this->gtinfo_.sendAnnounceMessage(message);
+                this->gtinfo_->sendAnnounceMessage(message);
 
                 if (timesequence_ >= 30 && timesequence_ <= 60)
Index: code/trunk/src/orxonox/gametypes/UnderAttack.h
===================================================================
--- code/trunk/src/orxonox/gametypes/UnderAttack.h	(revision 5781)
+++ code/trunk/src/orxonox/gametypes/UnderAttack.h	(revision 5929)
@@ -32,10 +32,9 @@
 #include "OrxonoxPrereqs.h"
 
-#include "interfaces/PawnListener.h"
 #include "TeamDeathmatch.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport UnderAttack : public TeamDeathmatch, public PawnListener
+    class _OrxonoxExport UnderAttack : public TeamDeathmatch
     {
         public:
@@ -54,7 +53,7 @@
 
         protected:
-            virtual void destroyedPawn(Pawn* pawn);
+            virtual void killedDestroyer();
 
-            Destroyer* destroyer_;
+            WeakPtr<Destroyer> destroyer_;
             unsigned int teams_;
             float gameTime_;
