Index: code/trunk/src/orxonox/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/CMakeLists.txt	(revision 6901)
+++ code/trunk/src/orxonox/CMakeLists.txt	(revision 7163)
@@ -32,4 +32,7 @@
   PlayerManager.cc
   Radar.cc
+  ChatHistory.cc
+  ChatInputHandler.cc
+#  Test.cc
 COMPILATION_BEGIN SceneCompilation.cc
   CameraManager.cc
@@ -55,11 +58,11 @@
   FIND_HEADER_FILES
   TOLUA_FILES
+    ChatInputHandler.h
     LevelManager.h
     MoodManager.h
     controllers/HumanController.h
-    interfaces/PickupCarrier.h
+    interfaces/Pickupable.h
+    infos/PlayerInfo.h
     sound/SoundManager.h
-  DEFINE_SYMBOL
-    "ORXONOX_SHARED_BUILD"
   PCH_FILE
     OrxonoxPrecompiledHeaders.h
@@ -75,6 +78,6 @@
     ${VORBIS_LIBRARY}
     ${OGG_LIBRARY}
-    tinyxml++_orxonox
-    tolua++_orxonox
+    tinyxml_orxonox
+    tolua_orxonox
     bullet_orxonox
     util
Index: code/trunk/src/orxonox/ChatHistory.cc
===================================================================
--- code/trunk/src/orxonox/ChatHistory.cc	(revision 7163)
+++ code/trunk/src/orxonox/ChatHistory.cc	(revision 7163)
@@ -0,0 +1,195 @@
+/*
+ *   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:
+ *      Sandro 'smerkli' Merkli
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ChatHistory.h"
+#include <core/ScopedSingletonManager.h>
+
+#ifndef CHATTEST
+namespace orxonox
+{
+  /* singleton */
+  ManageScopedSingleton( ChatHistory, ScopeID::Root, false );
+#endif
+
+  /* constructor */
+#ifndef CHATTEST
+  //ChatHistory::ChatHistory( BaseObject* creator ) : BaseObject(creator)
+  ChatHistory::ChatHistory()
+#else
+  ChatHistory::ChatHistory()
+#endif
+  {
+    /* register the object */
+#ifndef CHATTEST
+    RegisterObject(ChatHistory);
+#endif
+
+    this->hist_log_enabled = true;
+
+    /* Read setting for logfiles */
+    if( hist_log_enabled ) /* NOTE Make this a check for the logfile setting */
+    { this->chat_hist_openlog();
+
+      /* push starting line */
+      this->chat_hist_logline( "--- Logfile opened ---" );
+    }
+
+    /* Read setting for maximum number of lines and set limit */
+    this->hist_maxlines = 200; /* NOTE to be changed, 200 is just for testing */
+  }
+
+  /* destructor */
+  ChatHistory::~ChatHistory()
+  {
+    chat_hist_closelog();
+
+    /* clear list */
+    this->hist_buffer.clear();
+  }
+
+  /* react to incoming chat */
+  void ChatHistory::incomingChat(const std::string& message,
+    unsigned int senderID)
+  {
+    /* --> a) look up the actual name of the sender */
+    std::string text;
+
+#ifndef CHATTEST
+    /* get sender ID and prepend it to the message */
+    if (senderID != CLIENTID_UNKNOWN)
+    {
+      /* if we can't find anything, use "unknown" as default */
+      std::string name = "unknown";
+
+      PlayerInfo* player = PlayerManager::getInstance().getClient(senderID);
+      if (player)
+        name = player->getName();
+
+      text = name + ": " + message;
+    }
+    else
+      text = message;
+#else
+    text = message;
+#endif
+
+    /* add the line to the history */
+    this->chat_hist_addline( text );
+
+    /* add the line to the log */
+    this->chat_hist_logline( text );
+  }
+
+  /* Synchronize logfile onto the hard drive */ /* MARK MARK */
+  int ChatHistory::syncLog()
+  {
+    //if( this->hist_logfile )
+      //this->hist_logfile.sync();
+    return 0;
+  }
+
+  /* add a line to this history */
+  int ChatHistory::chat_hist_addline( const std::string& toadd )
+  {
+    /* crop history at the end if it's too large */
+    while( this->hist_buffer.size() > this->hist_maxlines+1 )
+      this->hist_buffer.pop_front();
+
+    /* push to the front of the history */
+    this->hist_buffer.push_back( toadd );
+    return 0;
+  }
+
+  /* log a line to a logfile */
+  int ChatHistory::chat_hist_logline( const std::string& toadd )
+  {
+    /* output the line to the file if logging is enabled */
+    if( this->hist_log_enabled )
+      this->hist_logfile << toadd << std::endl;
+    return 0;
+  }
+
+  /* open logfile */
+  int ChatHistory::chat_hist_openlog()
+  {
+    /* TODO: find out the name of the file to log to via settings
+     *       and set the this->hist_logfile_path variable to it
+     */
+#ifndef CHATTEST
+    this->hist_logfile.open( (PathConfig::getInstance().getLogPathString() +
+      "chatlog.log").c_str(),
+      std::fstream::out | std::fstream::app );
+#else
+    this->hist_logfile.open( "/tmp/chatlog.log",
+      std::fstream::out | std::fstream::app );
+#endif
+
+    /* TODO check whether this works (not sure how you'd like it?) */
+    if( !this->hist_logfile )
+    { this->hist_log_enabled = false;
+#ifndef CHATTEST
+      COUT(2) << "Warning: Could not open logfile." << std::endl;
+#endif
+    }
+
+    /* if it worked */
+    return 0;
+  }
+
+  /* close logfile */
+  void ChatHistory::chat_hist_closelog()
+  {
+    /* see if we've actually got a logfile */
+    if( this->hist_logfile )
+    {
+      /* yes, we've got one, add a line that shows we're closing it */
+      this->chat_hist_logline( "--- Logfile closed ---" );
+
+      /* actually close down the file */
+      this->hist_logfile.close();
+    }
+  }
+
+  /* output history for debugging */
+  void ChatHistory::debug_printhist()
+  {
+    /* create deque iterator */
+    std::deque<std::string>::iterator it;
+
+    /* output all the strings */
+    for( it = this->hist_buffer.begin(); it != this->hist_buffer.end();
+      ++it )
+      std::cout << *it << std::endl;
+
+    /* output size */
+    std::cout << "Size: " << hist_buffer.size() << std::endl;
+  }
+
+#ifndef CHATTEST
+}
+#endif
Index: code/trunk/src/orxonox/ChatHistory.h
===================================================================
--- code/trunk/src/orxonox/ChatHistory.h	(revision 7163)
+++ code/trunk/src/orxonox/ChatHistory.h	(revision 7163)
@@ -0,0 +1,149 @@
+/*
+ *   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:
+ *      Sandro 'smerkli' Merkli
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include <deque>
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <cassert>
+
+/* define this if you're unit testing */
+//#define CHATTEST
+
+#ifndef CHATTEST
+#include <OrxonoxPrereqs.h>
+#include <PlayerManager.h>
+#include <infos/PlayerInfo.h>
+#include <core/BaseObject.h>
+#include <network/ChatListener.h>
+#include <core/PathConfig.h>
+#include <util/Singleton.h>
+#endif
+
+#ifndef _ChatHistory_H__
+#define _ChatHistory_H__
+
+
+/* Class to implement chat history */
+#ifndef CHATTEST
+namespace orxonox
+{
+#endif
+
+  /* constructor */
+#ifndef CHATTEST
+  class _OrxonoxExport ChatHistory : public ChatListener,
+    public Singleton<ChatHistory>
+
+#else
+  class ChatHistory
+#endif
+  {
+    public:
+      /* constructors, destructors */
+#ifndef CHATTEST
+      ChatHistory();
+      friend class Singleton<ChatHistory>;
+#else
+      ChatHistory();
+#endif
+      virtual ~ChatHistory();
+
+
+    //protected:
+      /** what to do with incoming chat
+       *
+       * \param message The incoming message
+       * \param senderID Identification number of the sender
+       */
+      virtual void incomingChat(const std::string& message,
+        unsigned int senderID);
+
+      /** Synchronize logfile onto the hard drive
+       *
+       * \return 0 for success, other for error
+       */
+      int syncLog();
+
+      /** debug-print: output the whole history to stdout */
+      void debug_printhist();
+
+    private:
+      /* FIELDS */
+      /** Vector to store the history in */
+      std::deque<std::string> hist_buffer;
+
+      /** Maximum number of lines stored in this history */
+      unsigned int hist_maxlines;
+
+      /** is logging enabled? */
+      bool hist_log_enabled;
+
+      /** path of logfile on the file system */
+      std::string hist_logfile_path;
+
+      /** Output file stream for logfile */
+      std::ofstream hist_logfile;
+
+#ifndef CHATTEST
+      static ChatHistory* singletonPtr_s;
+#endif
+
+
+
+      /* METHODS */
+      /** Append line to chat history
+       *
+       * \param toadd The line to add to the history
+       * \return 0 for success, other for error TODO: Throw exception
+       */
+      int chat_hist_addline( const std::string& toadd );
+
+      /** Append line to logfile
+       *
+       * \param toadd The line to add to the logfile
+       * \return 0 for success, other for error TODO: Throw exception
+       */
+      int chat_hist_logline( const std::string& toadd );
+
+      /** open logfile to log to
+       *
+       * \return 0 for success,s other for error
+       */
+      int chat_hist_openlog();
+
+
+      /** close logfile */
+      void chat_hist_closelog();
+  };
+
+#ifndef CHATTEST
+}
+#endif
+
+#endif /* _ChatHistory_H__ */
Index: code/trunk/src/orxonox/ChatInputHandler.cc
===================================================================
--- code/trunk/src/orxonox/ChatInputHandler.cc	(revision 7163)
+++ code/trunk/src/orxonox/ChatInputHandler.cc	(revision 7163)
@@ -0,0 +1,345 @@
+/*
+ *   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:
+ *      Sandro 'smerkli' Merkli
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ChatInputHandler.h"
+#include <core/ScopedSingletonManager.h>
+#include "core/ConsoleCommand.h"
+#include "core/CoreIncludes.h"
+#include "core/GUIManager.h"
+#include "core/CorePrereqs.h"
+#include <CEGUIWindow.h>
+#include <elements/CEGUIListbox.h>
+#include <elements/CEGUIListboxItem.h>
+#include <elements/CEGUIListboxTextItem.h>
+#include <CEGUIWindowManager.h>
+#include <string>
+
+namespace orxonox
+{
+  /* singleton */
+  ManageScopedSingleton( ChatInputHandler, ScopeID::Graphics, false );
+
+  /* add commands to console */
+  SetConsoleCommandAlias( ChatInputHandler, activate_static, "startchat",
+    true );
+  SetConsoleCommandAlias( ChatInputHandler, activate_small_static,
+    "startchat_small", true );
+
+  /* constructor */
+  ChatInputHandler::ChatInputHandler()
+  {
+    /* register the object  */
+    RegisterObject(ChatInputHandler);
+
+    /* create necessary objects */
+    this->inpbuf = new InputBuffer();
+    this->disp_offset = 0;
+    assert( this->inpbuf != NULL );
+
+    /* generate chatbox ui and chatbox-inputonly ui */
+    GUIManager::getInstance().loadGUI( "ChatBox" );
+    GUIManager::getInstance().loadGUI( "ChatBox-inputonly" );
+
+    /* setup colors */
+    setupColors();
+
+    /* configure the input buffer */
+    configureInputBuffer();
+
+    this->inputState = InputManager::getInstance().createInputState( "chatinput", false, false, InputStatePriority::Dynamic );
+    this->inputState->setKeyHandler(this->inpbuf);
+  }
+
+  /* configure input buffer, sub for the constructor */
+  void ChatInputHandler::configureInputBuffer()
+  {
+    /* INSTALL CALLBACKS */
+    /* input has changed */
+    this->inpbuf->registerListener(this, &ChatInputHandler::inputChanged, true);
+
+    /* add a line */
+    this->inpbuf->registerListener(this, &ChatInputHandler::addline,         '\r',   false);
+    this->inpbuf->registerListener(this, &ChatInputHandler::addline,         '\n',   false);
+
+    /* backspace */
+    this->inpbuf->registerListener(this, &ChatInputHandler::backspace,       '\b',   true);
+    //this->inpbuf->registerListener(this, &ChatInputHandler::backspace,       '\177', true);
+
+    /* exit the chatinputhandler thingy (tbd) */
+    this->inpbuf->registerListener(this, &ChatInputHandler::exit,            '\033', true); // escape
+
+    /* delete character */
+    this->inpbuf->registerListener(this, &ChatInputHandler::deleteChar,      KeyCode::Delete);
+
+    /* cursor movement */
+    this->inpbuf->registerListener(this, &ChatInputHandler::cursorRight,     KeyCode::Right);
+    this->inpbuf->registerListener(this, &ChatInputHandler::cursorLeft,      KeyCode::Left);
+    this->inpbuf->registerListener(this, &ChatInputHandler::cursorEnd,       KeyCode::End);
+    this->inpbuf->registerListener(this, &ChatInputHandler::cursorHome,      KeyCode::Home);
+
+    /* GET WINDOW POINTERS */
+    input = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox/input" );
+    inputonly = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox-inputonly/input" );
+
+    /* get pointer to the history window */
+    CEGUI::Window *history = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox/history" );
+
+    /* cast it to a listbox */
+    lb_history = dynamic_cast<CEGUI::Listbox*>(history);
+
+    /* assert wee */
+    assert( lb_history );
+  }
+
+  /* setup the colors, sub for the constructor */
+  void ChatInputHandler::setupColors()
+  {
+    /* auto variables */
+    float red = 1.0, green = 0.5, blue = 0.5;
+    int i = 0;
+
+    // three loops: red tones, blue tones and green tones
+    // reds
+    for( i = 0; i < NumberOfColors/3; ++i )
+    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
+      assert( this->text_colors[ i ] );
+      green += 0.2, blue += 0.2;
+    }
+
+    // greens
+    red = 0.5, green = 1, blue = 0.5;
+    for( ; i < NumberOfColors*2/3; ++i )
+    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
+      assert( this->text_colors[ i ] );
+      red += 0.2, blue += 0.2;
+    }
+
+    // blues
+    red = 0.5, green = 0.5, blue = 1;
+    for( ; i < NumberOfColors; ++i )
+    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
+      assert( this->text_colors[ i ] );
+      red += 0.2, green += 0.2;
+    }
+  }
+
+
+  /* activate, deactivate */
+  void ChatInputHandler::activate_static()
+  { ChatInputHandler::getInstance().activate( true ); }
+
+  void ChatInputHandler::activate_small_static()
+  { ChatInputHandler::getInstance().activate( false ); }
+
+  void ChatInputHandler::activate( bool full )
+  {
+    /* start listening */
+    InputManager::getInstance().enterState("chatinput");
+
+    /* MARK add spawning of chat widget stuff here.*/
+    if( full )
+      GUIManager::getInstance().showGUI( "ChatBox" );
+    else
+      GUIManager::getInstance().showGUI( "ChatBox-inputonly" );
+
+    this->fullchat = full;
+  }
+
+  void ChatInputHandler::deactivate()
+  {
+    /* stop listening */
+    InputManager::getInstance().leaveState("chatinput");
+
+    /* un-spawning of chat widget stuff */
+    GUIManager::getInstance().hideGUI( "ChatBox" );
+    GUIManager::getInstance().hideGUI( "ChatBox-inputonly" );
+  }
+
+
+  /* subs for incomingChat */
+  void ChatInputHandler::sub_setcolor( CEGUI::ListboxTextItem *tocolor,
+    std::string name )
+  {
+    /* sanity checks */
+    if( !tocolor )
+      COUT(2) << "Empty ListBoxTextItem given to "
+        "ChatInputhandler::sub_setcolor().\n";
+
+    /* "hash" the name */
+    int hash = 0;
+    for( int i = name.length(); i > 0; --i )
+      hash += name[i-1];
+    hash = hash % this->NumberOfColors;
+
+    /* set the color according to the hash */
+    tocolor->setTextColours( *(this->text_colors[ hash ]) );
+  }
+
+  /* handle incoming chat */
+  void ChatInputHandler::incomingChat(const std::string& message,
+    unsigned int senderID)
+  {
+    /* look up the actual name of the sender */
+    std::string text, name = "unknown";
+
+    /* setup player name info */
+    if (senderID != CLIENTID_UNKNOWN)
+    {
+       PlayerInfo* player = PlayerManager::getInstance().getClient(senderID);
+       if (player)
+         name = player->getName();
+    }
+
+    /* assemble the text */
+    text = name + ": " + message;
+
+    /* create item */
+    CEGUI::ListboxTextItem *toadd = new CEGUI::ListboxTextItem( text );
+
+    /* setup colors */
+    sub_setcolor( toadd, name );
+
+    /* now add */
+    this->lb_history->addItem( dynamic_cast<CEGUI::ListboxItem*>(toadd) );
+    this->lb_history->ensureItemIsVisible(
+      dynamic_cast<CEGUI::ListboxItem*>(toadd) );
+
+    /* make sure the history handles it */
+    this->lb_history->handleUpdatedItemData();
+  }
+
+
+  /* sub for inputchanged */
+  void ChatInputHandler::sub_adjust_dispoffset( int maxlen,
+    int cursorpos,
+    int inplen )
+  {
+    /* already start offsetting 5 characters before end */
+    if( cursorpos+5 > maxlen )
+    {
+      /* always stay 5 characters ahead of end, looks better */
+      ((disp_offset = cursorpos-maxlen+5) >= 0) ? 1 : disp_offset = 0;
+
+      /* enforce visibility of cursor */
+      (disp_offset > cursorpos ) ? disp_offset = 0 : 1;
+    }
+
+    /* make sure we don't die at substr */
+    if( inplen <= disp_offset ) disp_offset = 0;
+  }
+
+  /* callbacks for InputBuffer */
+  void ChatInputHandler::inputChanged()
+  {
+    /* update the cursor and the window */
+    std::string raw = this->inpbuf->get();
+    int cursorpos = this->inpbuf->getCursorPosition();
+
+    /* get string before cursor */
+    std::string left = raw.substr( 0, cursorpos );
+
+    /* see if there's a string after the cursor */
+    std::string right = "";
+    if( raw.length() >= left.length()+1 )
+      right = raw.substr( cursorpos );
+
+    /* set the text */
+    std::string assembled = "$ " + left + "|" + right;
+
+    if( this->fullchat )
+    {
+      /* adjust curser position - magic number 5 for font width */
+      sub_adjust_dispoffset( (this->input->getUnclippedInnerRect().getWidth()/6),
+        cursorpos, assembled.length() );
+      this->input->setProperty( "Text", assembled.substr( disp_offset ) );
+    }
+    else
+    {
+      /* adjust curser position - magic number 5 for font width */
+      sub_adjust_dispoffset( (this->inputonly->getUnclippedInnerRect().getWidth()/6),
+        cursorpos, assembled.length() );
+      this->inputonly->setProperty( "Text", assembled.substr( disp_offset) );
+    }
+
+    /* reset display offset */
+    disp_offset = 0;
+  }
+
+  void ChatInputHandler::addline()
+  {
+    /* actually do send what was input */
+    /* a) get the string out of the inputbuffer */
+    std::string msgtosend = this->inpbuf->get();
+
+    if( msgtosend.length() == 0 )
+    { this->deactivate();
+      return;
+    }
+
+    /* b) clear the input buffer */
+    if (this->inpbuf->getSize() > 0)
+      this->inpbuf->clear();
+
+    /* c) send the chat via some call */
+    Host::Chat( msgtosend );
+
+    /* d) stop listening to input - only if this is not fullchat */
+    if( !this->fullchat )
+      this->deactivate();
+
+  }
+
+  void ChatInputHandler::backspace()
+  { this->inpbuf->removeBehindCursor(); }
+
+  void ChatInputHandler::deleteChar()
+  { this->inpbuf->removeAtCursor(); }
+
+  void ChatInputHandler::cursorRight()
+  { this->inpbuf->increaseCursor(); }
+
+  void ChatInputHandler::cursorLeft()
+  { this->inpbuf->decreaseCursor(); }
+
+  void ChatInputHandler::cursorEnd()
+  { this->inpbuf->setCursorToEnd(); }
+
+  void ChatInputHandler::cursorHome()
+  { this->inpbuf->setCursorToBegin(); }
+
+  void ChatInputHandler::exit()
+  {
+    /* b) clear the input buffer */
+    if (this->inpbuf->getSize() > 0)
+      this->inpbuf->clear();
+
+    /* d) stop listening to input  */
+    this->deactivate();
+  }
+
+}
Index: code/trunk/src/orxonox/ChatInputHandler.h
===================================================================
--- code/trunk/src/orxonox/ChatInputHandler.h	(revision 7163)
+++ code/trunk/src/orxonox/ChatInputHandler.h	(revision 7163)
@@ -0,0 +1,148 @@
+/*
+ *   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:
+ *      Sandro 'smerkli' Merkli
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ChatInputHandler_H__
+#define _ChatInputHandler_H__
+
+/* std includes */
+#include <deque>
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <cassert>
+#include <CEGUIForwardRefs.h>
+
+/* project includes */
+#include <OrxonoxPrereqs.h>
+#include <core/BaseObject.h>
+#include <core/PathConfig.h>
+
+#include "core/input/InputBuffer.h"
+#include "core/input/InputManager.h"
+#include "core/input/InputState.h"
+
+#include <network/ChatListener.h>
+#include <PlayerManager.h>
+#include <infos/PlayerInfo.h>
+
+#include "../libraries/network/Host.h"
+#include <util/Singleton.h>
+
+namespace orxonox // tolua_export
+{ // tolua_export
+  /* class to handle chat using an InputBuffer */
+  class _OrxonoxExport ChatInputHandler  // tolua_export
+    : public Singleton<ChatInputHandler>, public ChatListener
+  { // tolua_export
+    private:
+      /** Input buffer, to be used to catch input from the
+       * keyboard
+       */
+      InputBuffer *inpbuf;
+      int disp_offset, width;
+      bool fullchat;
+
+      /* colors for nickname coloring */
+      static const int NumberOfColors = 10;
+      CEGUI::colour *text_colors[ NumberOfColors ];
+
+      /** input state */
+      InputState *inputState;
+
+      /** setup input buffer, the constructor calls this */
+      void configureInputBuffer();
+
+      /** adjust display offset depending on cursor position */
+      void sub_adjust_dispoffset( int maxlen, int cursorpos, int inplen );
+
+      /** singleton pointer */
+      static ChatInputHandler* singletonPtr_s;
+
+      /** cegui window handles */
+      CEGUI::Window *input, *inputonly;
+
+      /** cegui handle for the history window */
+      CEGUI::Listbox *lb_history;
+
+      /* methods to deal with colors */
+      void sub_setcolor( CEGUI::ListboxTextItem *tocolor,
+        std::string name );
+
+      void setupColors();
+
+      /* callbacks for input handler */
+      void inputChanged();
+      void addline();
+      void backspace();
+      void deleteChar();
+      void cursorRight();
+      void cursorLeft();
+      void cursorEnd();
+      void cursorHome();
+      void exit();
+
+    public:
+      /** constructor */
+      ChatInputHandler();
+      friend class Singleton<ChatInputHandler>;
+
+      static ChatInputHandler& getInstance(void) { return Singleton<ChatInputHandler>::getInstance(); }  // tolua_export
+
+      /** start listening */
+      static void activate_static();
+
+      /** stop listening */
+      static void activate_small_static();
+
+      /** \param message the message text
+       * \param senderID ID of the player who sent the message
+       *
+       * Deal with incoming chat (which means in our case: Add it to the
+       * history window of the full chat window)
+       */
+      void incomingChat( const std::string& message,
+        unsigned int senderID );
+
+      /** \param full true means show full chat window with history,
+            false means show only an input line
+       *
+       * Show the chat window and redirect the game's keyboard input
+       * into it.
+       */
+      void activate( bool full );
+
+      /** Deactivate the chat window, meaning: hide it. */
+      void deactivate();  // tolua_export
+
+  };  // tolua_export
+
+
+}  // tolua_export
+
+
+#endif /*_ChatInputHandler_H__*/
Index: code/trunk/src/orxonox/Level.cc
===================================================================
--- code/trunk/src/orxonox/Level.cc	(revision 6901)
+++ code/trunk/src/orxonox/Level.cc	(revision 7163)
@@ -49,4 +49,5 @@
         RegisterObject(Level);
 
+
         this->registerVariables();
         this->xmlfilename_ = this->getFilename();
@@ -73,12 +74,14 @@
         XMLPortParam(Level, "gametype", setGametypeString, getGametypeString, xmlelement, mode).defaultValues("Gametype");
 
+        XMLPortObject(Level, MeshLodInformation, "lodinformation", addLodInfo, getLodInfo, xmlelement, mode);
         XMLPortObjectExtended(Level, BaseObject, "", addObject, getObject, xmlelement, mode, true, false);
-    }
+}
 
     void Level::registerVariables()
     {
-        registerVariable(this->xmlfilename_, VariableDirection::ToClient, new NetworkCallback<Level>(this, &Level::networkcallback_applyXMLFile));
-        registerVariable(this->name_,        VariableDirection::ToClient, new NetworkCallback<Level>(this, &Level::changedName));
-        registerVariable(this->description_, VariableDirection::ToClient);
+        registerVariable(this->xmlfilename_,            VariableDirection::ToClient, new NetworkCallback<Level>(this, &Level::networkcallback_applyXMLFile));
+        registerVariable(this->name_,                   VariableDirection::ToClient, new NetworkCallback<Level>(this, &Level::changedName));
+        registerVariable(this->description_,            VariableDirection::ToClient);
+        registerVariable(this->networkTemplateNames_,   VariableDirection::ToClient, new NetworkCallback<Level>(this, &Level::networkCallbackTemplatesChanged));
     }
 
@@ -95,4 +98,13 @@
 
         Loader::open(this->xmlfile_);
+    }
+
+    void Level::networkCallbackTemplatesChanged()
+    {
+        for( std::set<std::string>::iterator it = this->networkTemplateNames_.begin(); it!=this->networkTemplateNames_.end(); ++it )
+        {
+            assert(Template::getTemplate(*it));
+            Template::getTemplate(*it)->applyOn(this);
+        }
     }
 
@@ -125,4 +137,5 @@
         this->objects_.push_back(object);
         object->setGametype(this->getGametype());
+        object->setLevel(this);
     }
 
@@ -136,4 +149,21 @@
             ++i;
         }
+        return 0;
+    }
+
+    void Level::addLodInfo(MeshLodInformation* lodInformation)
+    {
+        std::string meshName = lodInformation->getMeshName();
+//         this->lodInformation_.insert(std::make_pair(meshName,lodInformation));
+        if( this->lodInformation_.find(meshName) != this->lodInformation_.end())
+          CCOUT(4) << "replacing lod information for " << meshName << endl;
+        this->lodInformation_[meshName] = lodInformation;
+    }
+
+    MeshLodInformation* Level::getLodInfo(std::string meshName) const
+    {
+        if(this->lodInformation_.find(meshName)!=this->lodInformation_.end())
+            return this->lodInformation_.find(meshName)->second;
+
         return 0;
     }
Index: code/trunk/src/orxonox/Level.h
===================================================================
--- code/trunk/src/orxonox/Level.h	(revision 6901)
+++ code/trunk/src/orxonox/Level.h	(revision 7163)
@@ -34,6 +34,8 @@
 #include <list>
 #include <string>
+#include <map>
 #include "core/BaseObject.h"
 #include "network/synchronisable/Synchronisable.h"
+#include "graphics/MeshLodInformation.h"
 
 namespace orxonox
@@ -46,5 +48,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             inline void setDescription(const std::string& description)
@@ -56,7 +57,16 @@
             void playerLeft(PlayerInfo* player);
 
+            MeshLodInformation* getLodInfo(std::string meshName) const;
+
+
         private:
+            void registerVariables();
             void addObject(BaseObject* object);
             BaseObject* getObject(unsigned int index) const;
+
+            void addLodInfo(MeshLodInformation* object);
+            void networkCallbackTemplatesChanged();
+//            const MeshLodInformation* getLodInfo(std::string meshName) const;
+//            MeshLodInformation* getLodInfo(unsigned int index) const;
 
             void setGametypeString(const std::string& gametype);
@@ -66,9 +76,10 @@
             void networkcallback_applyXMLFile();
 
-            std::string            description_;
-            std::string            gametype_;
-            std::string            xmlfilename_;
-            XMLFile*               xmlfile_;
-            std::list<BaseObject*> objects_;
+            std::string                    description_;
+            std::string                    gametype_;
+            std::string                    xmlfilename_;
+            XMLFile*                       xmlfile_;
+            std::list<BaseObject*>         objects_;
+            std::map<std::string,MeshLodInformation*>  lodInformation_;
     };
 }
Index: code/trunk/src/orxonox/LevelManager.cc
===================================================================
--- code/trunk/src/orxonox/LevelManager.cc	(revision 6901)
+++ code/trunk/src/orxonox/LevelManager.cc	(revision 7163)
@@ -70,4 +70,7 @@
     void LevelManager::requestActivity(Level* level)
     {
+        assert( std::find(this->levels_s.begin(), this->levels_s.end(), level)==this->levels_s.end() );
+        if( std::find(this->levels_s.begin(), this->levels_s.end(), level)!=this->levels_s.end() )
+            return; // level is already in list
         this->levels_s.push_back(level);
         if (this->levels_s.size() == 1)
Index: code/trunk/src/orxonox/Main.cc
===================================================================
--- code/trunk/src/orxonox/Main.cc	(revision 6901)
+++ code/trunk/src/orxonox/Main.cc	(revision 7163)
@@ -40,4 +40,5 @@
 #include "core/LuaState.h"
 #include "ToluaBindOrxonox.h"
+#include "ToluaBindNetwork.h"
 #include "Main.h"
 
@@ -51,4 +52,5 @@
 
 DeclareToluaInterface(Orxonox);
+DeclareToluaInterface(Network);
 
 namespace orxonox
Index: code/trunk/src/orxonox/MoodManager.cc
===================================================================
--- code/trunk/src/orxonox/MoodManager.cc	(revision 6901)
+++ code/trunk/src/orxonox/MoodManager.cc	(revision 7163)
@@ -32,4 +32,5 @@
 #include "core/CoreIncludes.h"
 #include "core/ScopedSingletonManager.h"
+#include "core/Resource.h"
 
 namespace orxonox
@@ -37,23 +38,36 @@
     ManageScopedSingleton(MoodManager, ScopeID::Root, false);
 
+    // Note: I'm (Kevin Young) not entirely sure whether that's good code style:
+    const std::string MoodManager::defaultMood_ = "default";
+
     MoodManager::MoodManager()
     {
         RegisterRootObject(MoodManager);
         this->setConfigValues();
+
+        // Need to use a variable to store old data because ResetConfigValues() doesn't seem to work.
+        oldMood_ = MoodManager::defaultMood_;
+        
+        // Checking for the existence of the folder for the default mood
+        const std::string& path = "ambient/" + MoodManager::defaultMood_ + "/.";
+        if (!Resource::exists(path))
+        {
+            // TODO: Non-fatal error handling (non-critical resource missing)
+            COUT(2) << "Mood Warning: Folder for default mood (" << MoodManager::defaultMood_ << ") does not exist!" << std::endl;
+        }
     }
 
     void MoodManager::setConfigValues()
     {
-        SetConfigValue(mood_, "default")
+        SetConfigValue(mood_, MoodManager::defaultMood_)
             .description("Sets the mood for the current level.")
             .callback(this, &MoodManager::checkMoodValidity);
     }
 
-    /** Sets the mood
-    @note
-        TODO: Inform dependent classes of mood change
-    */
+    /** Set a new mood
+     */
     void MoodManager::setMood(const std::string& mood)
     {
+        oldMood_ = mood_;
         ModifyConfigValue(mood_, set, mood);
     }
@@ -61,8 +75,10 @@
     void MoodManager::checkMoodValidity()
     {
-        // TODO: Insert new moods here & make this generic
-        if (mood_ != "default" && mood_ != "dnb")
+        //  Generic mood validation
+        const std::string& path = "ambient/" + mood_ + "/.";
+        if (!Resource::exists(path))
         {
-            ResetConfigValue(mood_);
+            COUT(3) << "Mood " << mood_ << " does not exist. Will not change." << std::endl;
+            this->setMood(oldMood_);
         }
         else
Index: code/trunk/src/orxonox/MoodManager.h
===================================================================
--- code/trunk/src/orxonox/MoodManager.h	(revision 6901)
+++ code/trunk/src/orxonox/MoodManager.h	(revision 7163)
@@ -38,4 +38,8 @@
 namespace orxonox
 {
+    /*
+    @brief
+        The MoodListener class is aware of a change in themes and directs that info to dependent classes.
+    */
     class _OrxonoxExport MoodListener : virtual public OrxonoxClass
     {
@@ -55,4 +59,8 @@
     };
 
+    /*
+    @brief
+        The MoodManager class serves to allow for different musical themes in the game.
+    */
     class _OrxonoxExport MoodManager : public Singleton<MoodManager>, public OrxonoxClass
     {
@@ -74,4 +82,6 @@
             // config values
             std::string mood_;
+            std::string oldMood_;
+            static const std::string defaultMood_;
 
             static MoodManager* singletonPtr_s;
Index: code/trunk/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- code/trunk/src/orxonox/OrxonoxPrereqs.h	(revision 6901)
+++ code/trunk/src/orxonox/OrxonoxPrereqs.h	(revision 7163)
@@ -82,4 +82,5 @@
     class ArtificialController;
     class Controller;
+    class DroneController;
     class HumanController;
     class ScriptController;
@@ -90,4 +91,5 @@
     class Asteroids;
     class Deathmatch;
+    class Dynamicmatch;
     class Gametype;
     class TeamBaseMatch;
@@ -135,5 +137,5 @@
     class OrxonoxOverlay;
     class OverlayGroup;
-    
+
     // pickup
     class PickupIdentifier;
@@ -161,4 +163,5 @@
     class CameraPosition;
     class ControllableEntity;
+    class Drone;
     class EffectContainer;
     class ExplosionChunk;
Index: code/trunk/src/orxonox/Radar.cc
===================================================================
--- code/trunk/src/orxonox/Radar.cc	(revision 6901)
+++ code/trunk/src/orxonox/Radar.cc	(revision 7163)
@@ -77,4 +77,26 @@
     }
 
+    void Radar::addRadarObject(RadarViewable* rv)
+    {
+        assert( this->radarObjects_.find(rv) == this->radarObjects_.end() );
+        this->radarObjects_.insert(rv);
+        // iterate through all radarlisteners and notify them
+        for (ObjectList<RadarListener>::iterator itListener = ObjectList<RadarListener>::begin(); itListener; ++itListener)
+        {
+            (*itListener)->addObject(rv);
+        }
+    }
+
+    void Radar::removeRadarObject(RadarViewable* rv)
+    {
+        assert( this->radarObjects_.find(rv) != this->radarObjects_.end() );
+        this->radarObjects_.erase(rv);
+        // iterate through all radarlisteners and notify them
+        for (ObjectList<RadarListener>::iterator itListener = ObjectList<RadarListener>::begin(); itListener; ++itListener)
+        {
+            (*itListener)->removeObject(rv);
+        }
+    }
+
     const RadarViewable* Radar::getFocus()
     {
@@ -109,11 +131,4 @@
         {
             (*itListener)->radarTick(dt);
-
-            for (ObjectList<RadarViewable>::iterator itElement = ObjectList<RadarViewable>::begin(); itElement; ++itElement)
-            {
-                if ((*itElement)->getRadarVisibility())
-                    if ((*itListener)->getRadarSensitivity() > (*itElement)->getRadarObjectCamouflage())
-                        (*itListener)->displayObject(*itElement, *itElement == this->focus_);
-            }
         }
     }
@@ -188,3 +203,11 @@
         }
     }
+
+    void Radar::radarObjectChanged(RadarViewable* rv)
+    {
+        for (ObjectList<RadarListener>::iterator itListener = ObjectList<RadarListener>::begin(); itListener; ++itListener)
+        {
+          (*itListener)->objectChanged(rv);
+        }
+    }
 }
Index: code/trunk/src/orxonox/Radar.h
===================================================================
--- code/trunk/src/orxonox/Radar.h	(revision 6901)
+++ code/trunk/src/orxonox/Radar.h	(revision 7163)
@@ -38,4 +38,5 @@
 
 #include <map>
+#include <set>
 #include <string>
 
@@ -48,4 +49,5 @@
     class _OrxonoxExport Radar : public Tickable
     {
+        friend class RadarViewable;
     public:
         Radar();
@@ -58,4 +60,6 @@
 
         void listObjects() const;
+        const std::set<RadarViewable*>& getRadarObjects() const
+            { return this->radarObjects_; }
 
         void releaseFocus();
@@ -66,8 +70,12 @@
 
         void updateFocus();
+        void addRadarObject(RadarViewable* rv);
+        void removeRadarObject(RadarViewable* rv);
+        void radarObjectChanged(RadarViewable* rv);
 
         ObjectListIterator<RadarViewable> itFocus_;
         RadarViewable* focus_;
         std::map<std::string, RadarViewable::Shape> objectTypes_;
+        std::set<RadarViewable*> radarObjects_;
         int objectTypeCounter_;
     };
Index: code/trunk/src/orxonox/Scene.cc
===================================================================
--- code/trunk/src/orxonox/Scene.cc	(revision 6901)
+++ code/trunk/src/orxonox/Scene.cc	(revision 7163)
@@ -47,4 +47,5 @@
 #include "Radar.h"
 #include "worldentities/WorldEntity.h"
+#include "Level.h"
 
 namespace orxonox
@@ -133,4 +134,5 @@
         registerVariable(this->bHasPhysics_,        VariableDirection::ToClient, new NetworkCallback<Scene>(this, &Scene::networkcallback_hasPhysics));
         registerVariable(this->bShadows_,           VariableDirection::ToClient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applyShadows));
+        registerVariable(this->getLevel(),          VariableDirection::ToClient, new NetworkCallback<Scene>(this, &Scene::changedLevel));
     }
 
Index: code/trunk/src/orxonox/Test.cc
===================================================================
--- code/trunk/src/orxonox/Test.cc	(revision 6901)
+++ code/trunk/src/orxonox/Test.cc	(revision 7163)
@@ -88,15 +88,17 @@
     void Test::registerVariables()
     {
-        registerVariable ( u1, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::checkU1 ));
-        registerVariable ( u2, VariableDirection::ToServer, new NetworkCallback<Test> ( this, &Test::checkU2 ));
-        registerVariable ( u3, Bidirectionality::ServerMaster, new NetworkCallback<Test> ( this, &Test::checkU3 ), true );
-        registerVariable ( u4, Bidirectionality::ClientMaster, new NetworkCallback<Test> ( this, &Test::checkU4 ), true );
+        registerVariable ( this->mySet_, VariableDirection::ToClient );
+      
+//         registerVariable ( u1, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::checkU1 ));
+//         registerVariable ( u2, VariableDirection::ToServer, new NetworkCallback<Test> ( this, &Test::checkU2 ));
+//         registerVariable ( u3, Bidirectionality::ServerMaster, new NetworkCallback<Test> ( this, &Test::checkU3 ), true );
+//         registerVariable ( u4, Bidirectionality::ClientMaster, new NetworkCallback<Test> ( this, &Test::checkU4 ), true );
     
-        registerVariable ( s1, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::checkS1 ));
-        registerVariable ( s2, VariableDirection::ToServer, new NetworkCallback<Test> ( this, &Test::checkS2 ));
-        registerVariable ( s3, Bidirectionality::ServerMaster, new NetworkCallback<Test> ( this, &Test::checkS3 ), true );
-        registerVariable ( s4, Bidirectionality::ClientMaster, new NetworkCallback<Test> ( this, &Test::checkS4 ), true );
+//         registerVariable ( s1, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::checkS1 ));
+//         registerVariable ( s2, VariableDirection::ToServer, new NetworkCallback<Test> ( this, &Test::checkS2 ));
+//         registerVariable ( s3, Bidirectionality::ServerMaster, new NetworkCallback<Test> ( this, &Test::checkS3 ), true );
+//         registerVariable ( s4, Bidirectionality::ClientMaster, new NetworkCallback<Test> ( this, &Test::checkS4 ), true );
     
-        registerVariable ( pointer_, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::printPointer ) );
+//         registerVariable ( pointer_, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::printPointer ) );
     }
   
Index: code/trunk/src/orxonox/Test.h
===================================================================
--- code/trunk/src/orxonox/Test.h	(revision 6901)
+++ code/trunk/src/orxonox/Test.h	(revision 7163)
@@ -35,4 +35,5 @@
 #include "tools/interfaces/Tickable.h"
 
+#include <set>
 
 typedef int TYPE;
@@ -49,5 +50,4 @@
 
       void setConfigValues();
-      void registerVariables();
 
       static void call(unsigned int clientID);
@@ -78,6 +78,6 @@
       void printPointer();
 
-      static void printV1(){ instance_->checkU1(); }
-      static void printV2(){ instance_->checkU2(); }
+      static void printV1(){ instance_->blub(); }
+      static void printV2(){ instance_->blub2(); }
       static void printV3(){ instance_->checkU3(); }
       static void printV4(){ instance_->checkU4(); }
@@ -86,4 +86,6 @@
 
     private:
+      void registerVariables();
+
       UTYPE u1;
       UTYPE u2;
@@ -97,6 +99,14 @@
 
       Test* pointer_;
+      
+      std::set<uint32_t> mySet_;
 
       static Test* instance_;
+      
+      void blub()
+      { mySet_.insert(2); }
+      
+      void blub2()
+      { for( std::set<uint32_t>::iterator it=mySet_.begin(); it!=mySet_.end(); ++it ) COUT(0) << *it << endl; }
   };
 }
Index: code/trunk/src/orxonox/collisionshapes/CollisionShape.h
===================================================================
--- code/trunk/src/orxonox/collisionshapes/CollisionShape.h	(revision 6901)
+++ code/trunk/src/orxonox/collisionshapes/CollisionShape.h	(revision 7163)
@@ -45,5 +45,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             inline void setPosition(const Vector3& position)
@@ -88,4 +87,6 @@
 
         private:
+            void registerVariables();
+
             Vector3                 position_;
             Quaternion              orientation_;
Index: code/trunk/src/orxonox/controllers/AIController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/AIController.cc	(revision 6901)
+++ code/trunk/src/orxonox/controllers/AIController.cc	(revision 7163)
@@ -23,5 +23,5 @@
  *      Fabian 'x3n' Landau
  *   Co-authors:
- *      ...
+ *      Dominik Solenicki
  *
  */
@@ -33,4 +33,5 @@
 #include "core/Executor.h"
 #include "worldentities/ControllableEntity.h"
+#include "worldentities/pawns/Pawn.h"
 
 namespace orxonox
@@ -56,43 +57,146 @@
         float maxrand = 100.0f / ACTION_INTERVAL;
 
-        // search enemy
-        random = rnd(maxrand);
-        if (random < 15 && (!this->target_))
-            this->searchNewTarget();
-
-        // forget enemy
-        random = rnd(maxrand);
-        if (random < 5 && (this->target_))
-            this->forgetTarget();
-
-        // next enemy
-        random = rnd(maxrand);
-        if (random < 10 && (this->target_))
-            this->searchNewTarget();
-
-        // fly somewhere
-        random = rnd(maxrand);
-        if (random < 50 && (!this->bHasTargetPosition_ && !this->target_))
-            this->searchRandomTargetPosition();
-
-        // stop flying
-        random = rnd(maxrand);
-        if (random < 10 && (this->bHasTargetPosition_ && !this->target_))
-            this->bHasTargetPosition_ = false;
-
-        // fly somewhere else
-        random = rnd(maxrand);
-        if (random < 30 && (this->bHasTargetPosition_ && !this->target_))
-            this->searchRandomTargetPosition();
-
-        // shoot
-        random = rnd(maxrand);
-        if (random < 75 && (this->target_ && !this->bShooting_))
-            this->bShooting_ = true;
-
-        // stop shooting
-        random = rnd(maxrand);
-        if (random < 25 && (this->bShooting_))
-            this->bShooting_ = false;
+        if (this->state_ == FREE)
+        {
+
+            if (this->formationFlight_)
+            {
+                // return to Master after being forced free
+                if (this->freedomCount_ == 1)
+                {
+                this->state_ = SLAVE;
+                this->freedomCount_ = 0;
+                }
+
+                random = rnd(maxrand);
+                if (random < 90 && (((!this->target_) || (random < 50 && this->target_)) && !this->forcedFree()))
+                    this->searchNewMaster();
+            }
+
+            // search enemy
+            random = rnd(maxrand);
+            if (random < 15 && (!this->target_))
+                this->searchNewTarget();
+
+            // forget enemy
+            random = rnd(maxrand);
+            if (random < 5 && (this->target_))
+                this->forgetTarget();
+
+            // next enemy
+            random = rnd(maxrand);
+            if (random < 10 && (this->target_))
+                this->searchNewTarget();
+
+            // fly somewhere
+            random = rnd(maxrand);
+            if (random < 50 && (!this->bHasTargetPosition_ && !this->target_))
+                this->searchRandomTargetPosition();
+
+            // stop flying
+            random = rnd(maxrand);
+            if (random < 10 && (this->bHasTargetPosition_ && !this->target_))
+                this->bHasTargetPosition_ = false;
+
+            // fly somewhere else
+            random = rnd(maxrand);
+            if (random < 30 && (this->bHasTargetPosition_ && !this->target_))
+                this->searchRandomTargetPosition();
+
+            // shoot
+            random = rnd(maxrand);
+            if (!(this->passive_) && random < 75 && (this->target_ && !this->bShooting_))
+                this->bShooting_ = true;
+
+            // stop shooting
+            random = rnd(maxrand);
+            if (random < 25 && (this->bShooting_))
+                this->bShooting_ = false;
+
+        }
+
+        if (this->state_ == SLAVE)
+        {
+
+        }
+
+        if (this->state_ == MASTER)
+        {
+
+
+            this->commandSlaves();
+
+            if  (this->specificMasterAction_ != NONE)
+                    this->specificMasterActionHold();
+
+            else {
+
+                 // make 180 degree turn - a specific Master Action
+                random = rnd(1000.0f);
+                if (random < 5)
+                   this->turn180Init();
+
+                // spin around - a specific Master Action
+                random = rnd(1000.0f);
+                if (random < 5)
+                   this->spinInit();
+
+                // follow a randomly chosen human - a specific Master Action
+                random = rnd(1000.0f);
+                if (random < 1)
+                   this->followRandomHumanInit();
+
+                 // lose master status (only if less than 4 slaves in formation)
+                random = rnd(maxrand);
+                if(random < 15/(this->slaves_.size()+1) && this->slaves_.size() < 4 )
+                   this->loseMasterState();
+
+                // look out for outher masters if formation is small
+                random = rnd(maxrand);
+                if(this->slaves_.size() < 3 && random < 20)
+                    this->searchNewMaster();
+
+                // search enemy
+                random = rnd(maxrand);
+                if (random < 15 && (!this->target_))
+                    this->searchNewTarget();
+
+                // forget enemy
+                random = rnd(maxrand);
+                if (random < 5 && (this->target_))
+                    this->forgetTarget();
+
+                // next enemy
+                random = rnd(maxrand);
+                if (random < 10 && (this->target_))
+                    this->searchNewTarget();
+
+                // fly somewhere
+                random = rnd(maxrand);
+                if (random < 50 && (!this->bHasTargetPosition_ && !this->target_))
+                    this->searchRandomTargetPosition();
+
+
+                // fly somewhere else
+                random = rnd(maxrand);
+                if (random < 30 && (this->bHasTargetPosition_ && !this->target_))
+                    this->searchRandomTargetPosition();
+
+                // shoot
+                random = rnd(maxrand);
+                if (!(this->passive_) && random < 9 && (this->target_ && !this->bShooting_))
+                {
+                this->bShooting_ = true;
+                this->forceFreeSlaves();
+                }
+
+                // stop shooting
+                random = rnd(maxrand);
+                if (random < 25 && (this->bShooting_))
+                    this->bShooting_ = false;
+
+            }
+        }
+
     }
 
@@ -102,12 +206,54 @@
             return;
 
-        if (this->target_)
-            this->aimAtTarget();
-
-        if (this->bHasTargetPosition_)
-            this->moveToTargetPosition();
-
-        if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(1000) && this->isLookingAtTarget(Ogre::Math::PI / 20.0f))
-            this->getControllableEntity()->fire(0);
+        if (this->state_ == MASTER)
+        {
+            if (this->specificMasterAction_ ==  NONE)
+            {
+                if (this->target_)
+                {
+				if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */
+                	this->forgetTarget();
+                else this->aimAtTarget();
+            }
+
+                if (this->bHasTargetPosition_)
+                    this->moveToTargetPosition();
+
+                if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(1000) && this->isLookingAtTarget(Ogre::Math::PI / 20.0f))
+                    this->getControllableEntity()->fire(0);
+            }
+
+            if (this->specificMasterAction_  == TURN180)
+                    this->turn180();
+
+            if (this->specificMasterAction_ == SPIN)
+                    this->spin();
+            if (this->specificMasterAction_ == FOLLOW)
+                    this->follow();
+        }
+
+        if (this->state_ == SLAVE)
+        {
+
+            if (this->bHasTargetPosition_)
+                this->moveToTargetPosition();
+
+        }
+
+         if (this->state_ == FREE)
+        {
+            if (this->target_)
+            {
+				if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */
+                	this->forgetTarget();
+                else this->aimAtTarget();
+            }
+
+            if (this->bHasTargetPosition_)
+                this->moveToTargetPosition();
+
+            if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(1000) && this->isLookingAtTarget(Ogre::Math::PI / 20.0f))
+                this->getControllableEntity()->fire(0);
+        }
 
         SUPER(AIController, tick, dt);
Index: code/trunk/src/orxonox/controllers/ArtificialController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/ArtificialController.cc	(revision 6901)
+++ code/trunk/src/orxonox/controllers/ArtificialController.cc	(revision 7163)
@@ -23,5 +23,5 @@
  *      Fabian 'x3n' Landau
  *   Co-authors:
- *      ...
+ *      Dominik Solenicki
  *
  */
@@ -29,13 +29,39 @@
 #include "ArtificialController.h"
 
+#include <vector>
+#include <climits>
+
+#include "util/Math.h"
+#include "core/ConsoleCommand.h"
 #include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
 #include "worldentities/ControllableEntity.h"
 #include "worldentities/pawns/Pawn.h"
 #include "worldentities/pawns/TeamBaseMatchBase.h"
 #include "gametypes/TeamDeathmatch.h"
+#include "gametypes/Dynamicmatch.h"
 #include "controllers/WaypointPatrolController.h"
+#include "controllers/NewHumanController.h"
+#include "controllers/DroneController.h"
 
 namespace orxonox
 {
+    SetConsoleCommand(ArtificialController, formationflight, true);
+    SetConsoleCommand(ArtificialController, masteraction, true);
+    SetConsoleCommand(ArtificialController, followme, true);
+    SetConsoleCommand(ArtificialController, passivebehaviour, true);
+    SetConsoleCommand(ArtificialController, formationsize, true);
+
+    static const unsigned int STANDARD_MAX_FORMATION_SIZE = 7;
+    static const int RADIUS_TO_SEARCH_FOR_MASTERS = 5000;
+    static const int FORMATION_LENGTH =  130;
+    static const int FORMATION_WIDTH =  110;
+    static const int FREEDOM_COUNT = 4; //seconds the slaves in a formation will be set free when master attacks an enemy
+    static const float SPEED_MASTER = 0.6f;
+    static const float ROTATEFACTOR_MASTER = 0.2f;
+    static const float SPEED_FREE = 0.8f;
+    static const float ROTATEFACTOR_FREE = 0.8f;
+
+
     ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator)
     {
@@ -43,6 +69,16 @@
 
         this->target_ = 0;
+        this->formationFlight_ = true;
+        this->passive_ = false;
+        this->maxFormationSize_ = STANDARD_MAX_FORMATION_SIZE;
+        this->myMaster_ = 0;
+        this->freedomCount_ = 0;
+        this->team_ = -1;
+        this->state_ = FREE;
+        this->specificMasterAction_ = NONE;
+        this->specificMasterActionHoldCount_  = 0;
         this->bShooting_ = false;
         this->bHasTargetPosition_ = false;
+        this->speedCounter_ = 0.2f;
         this->targetPosition_ = Vector3::ZERO;
 
@@ -52,4 +88,229 @@
     ArtificialController::~ArtificialController()
     {
+        if (this->isInitialized())
+        {
+            this->removeFromFormation();
+
+            for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it; ++it)
+            {
+                if (*it != this)
+                {
+                    if (it->myMaster_ == this)
+                    {
+                        COUT(1) << "error: " << this << " is still master in " << (*it) << std::endl;
+                        it->myMaster_ = 0;
+                    }
+
+                    while (true)
+                    {
+                        std::vector<ArtificialController*>::iterator it2 = std::find(it->slaves_.begin(), it->slaves_.end(), this);
+                        if (it2 != it->slaves_.end())
+                        {
+                            COUT(1) << "error: " << this << " is still slave in " << (*it) << std::endl;
+                            it->slaves_.erase(it2);
+                        }
+                        else
+                            break;
+                    }
+                }
+            }
+        }
+    }
+
+    void ArtificialController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(ArtificialController, XMLPort, xmlelement, mode);
+
+        XMLPortParam(ArtificialController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(-1);
+        XMLPortParam(ArtificialController, "formationFlight", setFormationFlight, getFormationFlight, xmlelement, mode).defaultValues(false);
+        XMLPortParam(ArtificialController, "formationSize", setFormationSize, getFormationSize, xmlelement, mode).defaultValues(STANDARD_MAX_FORMATION_SIZE);
+        XMLPortParam(ArtificialController, "passive", setPassive, getPassive, xmlelement, mode).defaultValues(false);
+    }
+
+// Documentation only here to get a faster overview for creating a useful documentation...
+
+    /**
+        @brief Activates / deactivates formationflight behaviour
+        @param form activate formflight if form is true
+    */
+    void ArtificialController::formationflight(const bool form)
+    {
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
+        {
+            Controller* controller = 0;
+
+            if (it->getController())
+                controller = it->getController();
+            else if (it->getXMLController())
+                controller = it->getXMLController();
+
+            if (!controller)
+                continue;
+
+            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
+
+            if (aiController)
+            {
+                aiController->formationFlight_ = form;
+                if (!form)
+                {
+                    aiController->removeFromFormation();
+                }
+            }
+        }
+    }
+
+    /**
+        @brief Get all masters to do a "specific master action"
+        @param action which action to perform (integer, so it can be called with a console command (tmp solution))
+    */
+    void ArtificialController::masteraction(const int action)
+    {
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
+        {
+            Controller* controller = 0;
+
+            if (it->getController())
+                controller = it->getController();
+            else if (it->getXMLController())
+                controller = it->getXMLController();
+
+            if (!controller)
+                continue;
+
+            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
+
+            if(aiController && aiController->state_ == MASTER)
+            {
+                if (action == 1)
+                    aiController->spinInit();
+                if (action == 2)
+                    aiController->turn180Init();
+            }
+        }
+    }
+
+    /**
+        @brief A human player gets followed by its nearest master. Initiated by console command, so far intended for demonstration puproses (possible future pickup).
+    */
+    void ArtificialController::followme()
+    {
+
+        Pawn *humanPawn = NULL;
+        NewHumanController *currentHumanController = NULL;
+        std::vector<ArtificialController*> allMasters;
+
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
+        {
+            Controller* controller = 0;
+
+            if (it->getController())
+                controller = it->getController();
+            else if (it->getXMLController())
+                controller = it->getXMLController();
+
+            if (!controller)
+                continue;
+
+            currentHumanController = orxonox_cast<NewHumanController*>(controller);
+
+            if(currentHumanController) humanPawn = *it;
+
+            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
+
+            if(aiController && aiController->state_ == MASTER)
+                allMasters.push_back(aiController);
+
+        }
+
+        if((humanPawn != NULL) && (allMasters.size() != 0))
+        {
+                float posHuman = humanPawn->getPosition().length();
+                float distance = 0.0f;
+                float minDistance = FLT_MAX;
+                int index = 0;
+                int i = 0;
+
+                for(std::vector<ArtificialController*>::iterator it = allMasters.begin(); it != allMasters.end(); it++, i++)
+                    {
+                        if (!ArtificialController::sameTeam((*it)->getControllableEntity(), humanPawn, (*it)->getGametype())) continue;
+                        distance = posHuman - (*it)->getControllableEntity()->getPosition().length();
+                        if(distance < minDistance) index = i;
+                    }
+                allMasters[index]->followInit(humanPawn);
+            }
+
+    }
+
+    /**
+        @brief Sets shooting behaviour of pawns.
+        @param passive if true, bots won't shoot.
+    */
+    void ArtificialController::passivebehaviour(const bool passive)
+    {
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
+        {
+            Controller* controller = 0;
+
+            if (it->getController())
+                controller = it->getController();
+            else if (it->getXMLController())
+                controller = it->getXMLController();
+
+            if (!controller)
+                continue;
+
+            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
+
+            if(aiController)
+            {
+                aiController->passive_ = passive;
+            }
+        }
+    }
+
+
+    /**
+        @brief Sets maximal formation size
+        @param size maximal formation size.
+    */
+    void ArtificialController::formationsize(const int size)
+    {
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
+        {
+            Controller* controller = 0;
+
+            if (it->getController())
+                controller = it->getController();
+            else if (it->getXMLController())
+                controller = it->getXMLController();
+
+            if (!controller)
+                continue;
+
+            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
+
+            if(aiController)
+            {
+                aiController->maxFormationSize_ = size;
+            }
+        }
+    }
+
+    /**
+        @brief Gets called when ControllableEntity is being changed. Resets the bot when it dies.
+    */
+    void ArtificialController::changedControllableEntity()
+    {
+        if (!this->getControllableEntity())
+            this->removeFromFormation();
+    }
+
+    void ArtificialController::removeFromFormation()
+    {
+        if (this->state_ == SLAVE || this->myMaster_) // slaves can also be temporary free, so check if myMaster_ is set
+            this->unregisterSlave();
+        else if (this->state_ == MASTER)
+            this->setNewMasterWithinFormation();
     }
 
@@ -59,24 +320,488 @@
             return;
 
+        // Slave uses special movement if its master is in FOLLOW mode
+        if(this->state_ == SLAVE && this->myMaster_ && this->myMaster_->specificMasterAction_ == FOLLOW)
+        {
+//             this->followForSlaves(target);
+//             return;
+        }
+
         Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
         float distance = (target - this->getControllableEntity()->getPosition()).length();
 
-        if (this->target_ || distance > 10)
-        {
-            // Multiply with 0.8 to make them a bit slower
-            this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
-            this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
-        }
-
-        if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
-            this->getControllableEntity()->moveFrontBack(-0.5f); // They don't brake with full power to give the player a chance
+
+        if(this->state_ == FREE)
+        {
+            if (this->target_ || distance > 10)
+            {
+                // Multiply with ROTATEFACTOR_FREE to make them a bit slower
+                this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x);
+                this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y);
+            }
+
+            if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
+            {
+              this->getControllableEntity()->moveFrontBack(-0.05f); // They don't brake with full power to give the player a chance
+            } else this->getControllableEntity()->moveFrontBack(SPEED_FREE);
+        }
+
+
+
+        if(this->state_ == MASTER)
+        {
+            if (this->target_ || distance > 10)
+            {
+                this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x);
+                this->getControllableEntity()->rotatePitch(ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y);
+            }
+
+            if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
+            {
+                this->getControllableEntity()->moveFrontBack(-0.05f);
+            } else this->getControllableEntity()->moveFrontBack(SPEED_MASTER);
+        }
+
+
+
+        if(this->state_ == SLAVE)
+        {
+
+           this->getControllableEntity()->rotateYaw(-2.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x);
+           this->getControllableEntity()->rotatePitch(2.0f * ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y);
+
+            if (distance < 300)
+            {
+                if (distance < 40)
+                {
+                    this->getControllableEntity()->moveFrontBack(0.8f*SPEED_MASTER);
+                } else this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER);
+
+            } else {
+                this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER + distance/300.0f);
+            }
+        }
+    }
+
+    void ArtificialController::moveToTargetPosition()
+    {
+        this->moveToPosition(this->targetPosition_);
+    }
+
+
+    /**
+        @brief Unregisters a slave from its master. Initiated by a slave.
+    */
+    void ArtificialController::unregisterSlave()
+    {
+        if (this->myMaster_)
+        {
+            std::vector<ArtificialController*>::iterator it = std::find(this->myMaster_->slaves_.begin(), this->myMaster_->slaves_.end(), this);
+            if (it != this->myMaster_->slaves_.end())
+                this->myMaster_->slaves_.erase(it);
+        }
+
+        this->myMaster_ = 0;
+        this->state_ = FREE;
+    }
+
+    void ArtificialController::searchNewMaster()
+    {
+
+        if (!this->getControllableEntity())
+            return;
+
+        this->targetPosition_ = this->getControllableEntity()->getPosition();
+        this->forgetTarget();
+        int teamSize = 0;
+        //go through all pawns
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
+        {
+            //same team?
+            if (!ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
+                continue;
+
+            //has it an ArtificialController?
+            Controller* controller = 0;
+
+            if (it->getController())
+                controller = it->getController();
+            else if (it->getXMLController())
+                controller = it->getXMLController();
+
+            if (!controller)
+                continue;
+
+            //is pawn oneself?
+            if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity())
+                continue;
+
+            teamSize++;
+
+            ArtificialController *newMaster = orxonox_cast<ArtificialController*>(controller);
+
+            //is it a master?
+            if (!newMaster || newMaster->state_ != MASTER)
+                continue;
+
+            float distance = (it->getPosition() - this->getControllableEntity()->getPosition()).length();
+
+            // is pawn in range?
+            if (distance < RADIUS_TO_SEARCH_FOR_MASTERS)
+            {
+                if(newMaster->slaves_.size() > this->maxFormationSize_) continue;
+
+                for(std::vector<ArtificialController*>::iterator itSlave = this->slaves_.begin(); itSlave != this->slaves_.end(); itSlave++)
+                {
+                    (*itSlave)->myMaster_ = newMaster;
+                    newMaster->slaves_.push_back(*itSlave);
+                }
+                this->slaves_.clear();
+                this->state_ = SLAVE;
+
+                this->myMaster_ = newMaster;
+                newMaster->slaves_.push_back(this);
+
+                break;
+            }
+        }
+
+        if (this->state_ != SLAVE  && teamSize != 0)
+        {
+            this->state_ = MASTER;
+            this->myMaster_ = 0;
+        }
+    }
+
+    /**
+        @brief Commands the slaves of a master into a formation. Sufficiently fast not to be called within tick. Initiated by a master.
+    */
+    void ArtificialController::commandSlaves()
+    {
+        if(this->state_ != MASTER) return;
+
+        Quaternion orient = this->getControllableEntity()->getOrientation();
+        Vector3 dest = this->getControllableEntity()->getPosition();
+
+        // 1 slave: follow
+        if (this->slaves_.size() == 1)
+        {
+            dest += 4*orient*WorldEntity::BACK;
+            this->slaves_.front()->setTargetPosition(dest);
+        }
         else
-            this->getControllableEntity()->moveFrontBack(0.8f);
-    }
-
-    void ArtificialController::moveToTargetPosition()
-    {
-        this->moveToPosition(this->targetPosition_);
-    }
+        {
+            dest += 1.0f*orient*WorldEntity::BACK;
+            Vector3 pos = Vector3::ZERO;
+            int i = 1;
+
+            for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
+            {
+                pos = Vector3::ZERO;
+                if (i <= 1) pos += dest  + FORMATION_WIDTH*(orient*WorldEntity::LEFT);
+                if (i == 2) pos += dest  + FORMATION_WIDTH*(orient*WorldEntity::RIGHT);
+                if (i == 3) pos += dest  + FORMATION_WIDTH*(orient*WorldEntity::UP);
+                if (i >= 4)
+                {
+                    pos += dest  + FORMATION_WIDTH*(orient*WorldEntity::DOWN);
+                    i = 1;
+                    dest += FORMATION_LENGTH*(orient*WorldEntity::BACK);
+                    (*it)->setTargetPosition(pos);
+                    continue;
+                }
+                i++;
+                (*it)->setTargetPosition(pos);
+            }
+        }
+    }
+
+    /**
+        @brief Sets a new master within the formation. Called by a master.
+    */
+    void ArtificialController::setNewMasterWithinFormation()
+    {
+        if(this->state_ != MASTER) return;
+
+        if (!this->slaves_.empty())
+        {
+            ArtificialController *newMaster = this->slaves_.back();
+            this->slaves_.pop_back();
+
+            newMaster->state_ = MASTER;
+            newMaster->slaves_ = this->slaves_;
+            newMaster->myMaster_ = 0;
+
+            for(std::vector<ArtificialController*>::iterator it = newMaster->slaves_.begin(); it != newMaster->slaves_.end(); it++)
+            {
+                (*it)->myMaster_ = newMaster;
+            }
+        }
+
+        this->slaves_.clear();
+        this->specificMasterAction_ = NONE;
+        this->state_ = FREE;
+    }
+
+    /**
+        @brief Frees all slaves form a master. Initiated by a master.
+    */
+    void ArtificialController::freeSlaves()
+    {
+        if(this->state_ != MASTER) return;
+
+        for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
+        {
+            (*it)->state_ = FREE;
+            (*it)->myMaster_ = 0;
+        }
+        this->slaves_.clear();
+    }
+
+    /**
+        @brief Master sets its slaves free for @var FREEDOM_COUNT seconds.
+    */
+    void ArtificialController::forceFreeSlaves()
+    {
+        if(this->state_ != MASTER) return;
+
+        for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
+        {
+            (*it)->state_ = FREE;
+            (*it)->forceFreedom();
+            (*it)->targetPosition_ = this->targetPosition_;
+            (*it)->bShooting_ = true;
+//             (*it)->getControllableEntity()->fire(0);// fire once for fun
+        }
+    }
+
+    void ArtificialController::loseMasterState()
+    {
+        this->freeSlaves();
+        this->state_ = FREE;
+    }
+
+
+    void ArtificialController::forceFreedom()
+    {
+        this->freedomCount_ = FREEDOM_COUNT;
+    }
+
+    /**
+        @brief Checks wether caller has been forced free, decrements time to stay forced free.
+        @return true if forced free.
+    */
+    bool ArtificialController::forcedFree()
+    {
+        if(this->freedomCount_ > 0)
+        {
+            this->freedomCount_--;
+            return true;
+        } else return false;
+    }
+
+    /**
+        @brief Used to continue a "specific master action" for a certain time and resuming normal behaviour after.
+    */
+    void ArtificialController::specificMasterActionHold()
+    {
+        if(this->state_ != MASTER) return;
+
+        if (specificMasterActionHoldCount_ == 0)
+         {
+            this->specificMasterAction_ = NONE;
+            this->searchNewTarget();
+         }
+        else specificMasterActionHoldCount_--;
+    }
+
+    /**
+        @brief Master initializes a 180 degree turn. Leads to a "specific master action".
+    */
+    void ArtificialController::turn180Init()
+    {
+        if(this->state_ != MASTER) return;
+
+        Quaternion orient = this->getControllableEntity()->getOrientation();
+
+        this->setTargetPosition(this->getControllableEntity()->getPosition() + 1000.0f*orient*WorldEntity::BACK);
+
+        this->specificMasterActionHoldCount_ = 4;
+
+        this->specificMasterAction_ = TURN180;
+    }
+
+    /**
+        @brief Execute the 180 degree turn. Called within tick.
+    */
+    void ArtificialController::turn180()
+    {
+            Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->targetPosition_);
+
+            this->getControllableEntity()->rotateYaw(-2.0f * sgn(coord.x) * coord.x*coord.x);
+            this->getControllableEntity()->rotatePitch(2.0f * sgn(coord.y) * coord.y*coord.y);
+
+            this->getControllableEntity()->moveFrontBack(SPEED_MASTER);
+    }
+
+    /**
+        @brief Master initializes a spin around its looking direction axis. Leads to a "specific master action".
+    */
+    void ArtificialController::spinInit()
+    {
+        if(this->state_ != MASTER) return;
+        this->specificMasterAction_ = SPIN;
+        this->specificMasterActionHoldCount_ = 10;
+    }
+
+    /**
+        @brief Execute the spin. Called within tick.
+    */
+    void ArtificialController::spin()
+    {
+            this->moveToTargetPosition();
+            this->getControllableEntity()->rotateRoll(0.8f);
+    }
+
+    /**
+        @brief Master begins to follow a pawn. Is a "specific master action".
+        @param pawn pawn to follow.
+        @param alaways follows pawn forever if true (false if omitted).
+        @param secondsToFollow seconds to follow the pawn if always is false. Will follow pawn 100 seconds if omitted (set in header).
+    */
+    void ArtificialController::followInit(Pawn* pawn, const bool always, const int secondsToFollow)
+    {
+        if (pawn == NULL || this->state_ != MASTER)
+            return;
+        this->specificMasterAction_  =  FOLLOW;
+
+        this->setTarget(pawn);
+        if (!always)
+            this->specificMasterActionHoldCount_ = secondsToFollow;
+        else
+            this->specificMasterActionHoldCount_ = INT_MAX; //for now...
+
+    }
+
+
+    /**
+        @brief Master begins to follow a randomly chosen human player of the same team. Is a "specific master action".
+    */
+    void ArtificialController::followRandomHumanInit()
+    {
+
+        Pawn *humanPawn = NULL;
+        NewHumanController *currentHumanController = NULL;
+
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
+        {
+            if (!it->getController())
+                continue;
+
+            currentHumanController = orxonox_cast<NewHumanController*>(it->getController());
+            if(currentHumanController)
+            {
+                if (!ArtificialController::sameTeam(this->getControllableEntity(), *it, this->getGametype())) continue;
+                humanPawn = *it;
+                break;
+            }
+        }
+
+        if((humanPawn != NULL))
+                this->followInit(humanPawn);
+    }
+
+    /**
+        @brief Master follows target with adjusted speed. Called within tick.
+    */
+    void ArtificialController::follow()
+    {
+        if (this->target_)
+            this->moveToPosition(this->target_->getPosition());
+        else
+            this->specificMasterActionHoldCount_ = 0;
+/*
+        if (!this->getControllableEntity())
+            return;
+
+        float distance = (this->target_->getPosition() - this->getControllableEntity()->getPosition()).length();
+
+        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->target_->getPosition());
+
+
+        this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
+        this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
+
+        float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->target_->getVelocity().squaredLength();
+
+COUT(0) << "~follow distance: " << distance << "SpeedCounter: " << this->speedCounter_ << "~speedDiv: " << speedDiv << std::endl;
+        if (distance < 800)
+        {
+            if (distance < 200)
+            {
+                this->speedCounter_ -= 0.5f;
+                if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f;
+                this->getControllableEntity()->moveFrontBack(speedCounter_);
+            } else {
+                if(speedDiv < 0)
+                    this->speedCounter_ +=  0.01f;
+                else
+                    this->speedCounter_ -= 0.05f;
+                this->getControllableEntity()->moveFrontBack(speedCounter_);
+            }
+
+        } else {
+            this->speedCounter_ += 0.05f;
+            this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f);
+        }
+//         if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0;
+
+*/
+    }
+
+
+    /**
+        @brief Slave moving behaviour when master is following a pawn, gets redirected from moveToPosition(const Vector3& target)). Called within tick.
+    */
+    void ArtificialController::followForSlaves(const Vector3& target)
+    {
+
+/*
+        if (!this->getControllableEntity() && !this->myMaster_ && this->myMaster_->state_ != FOLLOW && !this->myMaster_->target_)
+            return;
+
+        float distance = (target - this->getControllableEntity()->getPosition()).length();
+
+        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
+
+
+        this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
+        this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
+
+
+        float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->myMaster_->target_->getVelocity().squaredLength();
+
+
+         if (distance < 800)
+        {
+            if (distance < 200)
+            {
+                this->speedCounter_ -= 5.0f;
+                if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f;
+                this->getControllableEntity()->moveFrontBack(speedCounter_);
+            } else {
+                if(speedDiv < 0)
+                    this->speedCounter_ +=  0.01f;
+                else
+                    this->speedCounter_ -= 0.05f;
+                this->getControllableEntity()->moveFrontBack(speedCounter_);
+            }
+
+        } else {
+            this->speedCounter_ += 0.05f;
+            this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f);
+        }
+//         if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0;
+*/
+    }
+
 
     void ArtificialController::setTargetPosition(const Vector3& target)
@@ -111,4 +836,8 @@
         {
             if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
+                continue;
+
+            /* So AI won't choose invisible Spaceships as target */
+            if (!it->getRadarVisibility())
                 continue;
 
@@ -144,5 +873,5 @@
         this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO);
 
-        Pawn* pawn = dynamic_cast<Pawn*>(this->getControllableEntity());
+        Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
         if (pawn)
             pawn->setAimPosition(this->targetPosition_);
@@ -188,15 +917,25 @@
         int team2 = -1;
 
-        if (entity1->getXMLController())
-        {
-            WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity1->getXMLController());
-            if (wpc)
-                team1 = wpc->getTeam();
-        }
-        if (entity2->getXMLController())
-        {
-            WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity2->getXMLController());
-            if (wpc)
-                team2 = wpc->getTeam();
+        Controller* controller = 0;
+        if (entity1->getController())
+            controller = entity1->getController();
+        else
+            controller = entity1->getXMLController();
+        if (controller)
+        {
+            ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
+            if (ac)
+                team1 = ac->getTeam();
+        }
+
+        if (entity2->getController())
+            controller = entity2->getController();
+        else
+            controller = entity2->getXMLController();
+        if (controller)
+        {
+            ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
+            if (ac)
+                team2 = ac->getTeam();
         }
 
@@ -245,4 +984,34 @@
         }
 
+        DroneController* droneController = 0;
+        droneController = orxonox_cast<DroneController*>(entity1->getController());
+        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)
+            return true;
+        droneController = orxonox_cast<DroneController*>(entity2->getController());
+        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)
+            return true;
+        DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController());
+        DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController());
+        if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner())
+            return true;
+
+        Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype);
+        if (dynamic)
+        {
+            if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;}
+
+            if (entity1->getPlayer())
+                team1 = dynamic->getParty(entity1->getPlayer());
+
+            if (entity2->getPlayer())
+                team2 = dynamic->getParty(entity2->getPlayer());
+
+            if (team1 ==-1 ||team2 ==-1 ) {return false;}
+            else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;}
+            else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;}
+            else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;}
+            else return true;
+        }
+
         return (team1 == team2 && team1 != -1);
     }
Index: code/trunk/src/orxonox/controllers/ArtificialController.h
===================================================================
--- code/trunk/src/orxonox/controllers/ArtificialController.h	(revision 6901)
+++ code/trunk/src/orxonox/controllers/ArtificialController.h	(revision 7163)
@@ -23,5 +23,5 @@
  *      Fabian 'x3n' Landau
  *   Co-authors:
- *      ...
+ *      Dominik Solenicki
  *
  */
@@ -32,6 +32,9 @@
 #include "OrxonoxPrereqs.h"
 
+#include <vector>
+
 #include "util/Math.h"
 #include "Controller.h"
+#include "controllers/NewHumanController.h"
 
 namespace orxonox
@@ -43,11 +46,76 @@
             virtual ~ArtificialController();
 
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
             void abandonTarget(Pawn* target);
 
+            inline void setTeam(int team)
+                { this->team_ = team; }
+            inline int getTeam() const
+                { return this->team_; }
+
+            inline void setFormationFlight(bool formation)
+                { this->formationFlight_ = formation; }
+            inline bool getFormationFlight() const
+                { return this->formationFlight_; }
+
+            inline void setFormationSize(int size)
+                { this->maxFormationSize_ = size; }
+            inline int getFormationSize() const
+                { return this->maxFormationSize_; }
+
+            inline void setPassive(bool passive)
+                { this->passive_ = passive; }
+            inline bool getPassive() const
+                { return this->passive_; }
+
+            virtual void changedControllableEntity();
+
+            static void formationflight(const bool form);
+            static void masteraction(const int action);
+            static void followme();
+            static void passivebehaviour(const bool passive);
+            static void formationsize(const int size);
+
         protected:
-            void targetDied();
+
+            int team_;
+            bool formationFlight_;
+            bool passive_;
+            unsigned int maxFormationSize_;
+            int freedomCount_;
+            enum State {SLAVE, MASTER, FREE};
+            State state_;
+            std::vector<ArtificialController*> slaves_;
+            ArtificialController *myMaster_;
+            enum SpecificMasterAction {NONE, HOLD, SPIN, TURN180, FOLLOW};
+            SpecificMasterAction specificMasterAction_;
+            int specificMasterActionHoldCount_;
+            float speedCounter_; //for speed adjustment when following
 
             void moveToPosition(const Vector3& target);
             void moveToTargetPosition();
+
+            void removeFromFormation();
+            void unregisterSlave();
+            void searchNewMaster();
+            void commandSlaves();
+            void setNewMasterWithinFormation();
+
+            void freeSlaves();
+            void forceFreeSlaves();
+            void loseMasterState();
+            void forceFreedom();
+            bool forcedFree();
+
+            void specificMasterActionHold();
+            void turn180Init();
+            void turn180();
+            void spinInit();
+            void spin();
+            void followInit(Pawn* pawn, const bool always = false, const int secondsToFollow = 100);
+            void followRandomHumanInit();
+            void follow();
+            void followForSlaves(const Vector3& target);
 
             void setTargetPosition(const Vector3& target);
@@ -61,4 +129,6 @@
             bool isCloseAtTarget(float distance) const;
             bool isLookingAtTarget(float angle) const;
+
+            void targetDied();
 
             static bool sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype); // hack
Index: code/trunk/src/orxonox/controllers/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/controllers/CMakeLists.txt	(revision 6901)
+++ code/trunk/src/orxonox/controllers/CMakeLists.txt	(revision 7163)
@@ -8,3 +8,4 @@
   WaypointController.cc
   WaypointPatrolController.cc
+  DroneController.cc
 )
Index: code/trunk/src/orxonox/controllers/DroneController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/DroneController.cc	(revision 7163)
+++ code/trunk/src/orxonox/controllers/DroneController.cc	(revision 7163)
@@ -0,0 +1,149 @@
+/*
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DroneController.h"
+#include "worldentities/Drone.h"
+#include "util/Math.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor.
+    */
+    CreateFactory(DroneController);
+
+    static const float ACTION_INTERVAL = 1.0f;
+
+    DroneController::DroneController(BaseObject* creator) : ArtificialController(creator)
+    {
+        RegisterObject(DroneController);
+
+        this->owner_ = 0;
+        this->drone_ = 0;
+        this->isShooting_ = false;
+
+        this->actionTimer_.setTimer(ACTION_INTERVAL, true, createExecutor(createFunctor(&DroneController::action, this)));
+
+        this->owner_.setCallback(createFunctor(&DroneController::ownerDied, this));
+    }
+
+    DroneController::~DroneController()
+    {
+    }
+
+    void DroneController::setOwner(Pawn* owner){
+        this->owner_ = owner;
+    }
+
+    void DroneController::setDrone(Drone* drone)
+    {
+        this->drone_ = drone;
+        this->setControllableEntity(drone);
+    }
+
+    void DroneController::action()
+    {
+        float random;
+        float maxrand = 100.0f / ACTION_INTERVAL;
+        float distanceToTargetSquared = 0;
+
+        if (this->target_)
+            distanceToTargetSquared = (getDrone()->getWorldPosition() - this->target_->getWorldPosition()).squaredLength();
+
+        random = rnd(maxrand);
+        if ( random < 30 || (!this->target_) || distanceToTargetSquared > (this->getDrone()->getMaxShootingRange()*this->getDrone()->getMaxShootingRange()))
+            this->searchNewTarget();
+    }
+
+    /**
+    @brief
+        The controlling happens here. This method defines what the controller has to do each tick.
+    @param dt
+        The duration of the tick.
+    */
+    void DroneController::tick(float dt)
+    {
+        if (this->getDrone() && this->getOwner())
+        {
+            if (this->target_)
+            {
+                float distanceToTargetSquared = (this->getDrone()->getWorldPosition() - this->target_->getWorldPosition()).squaredLength();
+                if (distanceToTargetSquared < (this->getDrone()->getMaxShootingRange()*this->getDrone()->getMaxShootingRange()))
+                {
+                    this->isShooting_ = true;
+                    this->aimAtTarget();
+                    this->getDrone()->fire(0);
+                }
+            }
+
+            float maxDistanceSquared = this->getDrone()->getMaxDistanceToOwner()*this->getDrone()->getMaxDistanceToOwner();
+            float minDistanceSquared = this->getDrone()->getMinDistanceToOwner()*this->getDrone()->getMinDistanceToOwner();
+            if ((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength()  > maxDistanceSquared)
+            {
+                this->moveToPosition(this->getOwner()->getWorldPosition()); //fly towards owner
+            }
+            else if((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength() < minDistanceSquared)
+            {
+                this->moveToPosition(-this->getOwner()->getWorldPosition()); //fly away from owner
+            }
+            else if (!this->isShooting_)
+            {
+                float random = rnd(2.0f);
+                float randomSelection = rnd(6.0f);
+                if((int)randomSelection==0) drone_->moveUpDown(random);
+                else if((int)randomSelection==1) drone_->moveRightLeft(random);
+                else if((int)randomSelection==2) drone_->moveFrontBack(random);
+                else if((int)randomSelection==3) drone_->rotateYaw(random);
+                else if((int)randomSelection==4) drone_->rotatePitch(random);
+                else if((int)randomSelection==5) drone_->rotateRoll(random);
+            }
+
+            this->isShooting_ = false;
+        }
+
+        SUPER(AIController, tick, dt);
+
+    }
+
+    void DroneController::ownerDied()
+    {
+//         if (this->target_) {            //Drone has some kind of Stockholm-Syndrom --> gets attached to Owners Killer
+//             this->setOwner(target_);
+//             this->searchNewTarget();
+//         }
+        if (this->drone_)
+            this->drone_->destroy();
+        else
+            this->destroy();
+    }
+}
Index: code/trunk/src/orxonox/controllers/DroneController.h
===================================================================
--- code/trunk/src/orxonox/controllers/DroneController.h	(revision 7163)
+++ code/trunk/src/orxonox/controllers/DroneController.h	(revision 7163)
@@ -0,0 +1,77 @@
+/*
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DroneController_H__
+#define _DroneController_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "AIController.h"
+#include "core/WeakPtr.h"
+#include "tools/interfaces/Tickable.h"
+
+#include "tools/Timer.h"
+
+
+namespace orxonox
+{
+    /**
+    @brief
+        Controller for the Drone of the PPS tutorial.
+    @author
+        Oli Scheuss
+    */
+    class _OrxonoxExport DroneController : public ArtificialController, public Tickable
+    {
+        public:
+            DroneController(BaseObject* creator);
+            virtual ~DroneController();
+
+            virtual void tick(float dt); //!< The controlling happens here. This method defines what the controller has to do each tick.
+
+            void setOwner(Pawn* owner);
+            inline Pawn* getOwner() const
+                { return this->owner_; }
+
+            void setDrone(Drone*  drone);
+            inline Drone* getDrone() const
+                { return this->drone_; }
+
+        protected:
+            virtual void action();
+            void ownerDied();
+            bool isShooting_;
+
+        private:
+            Timer actionTimer_;
+            WeakPtr<Pawn> owner_;
+            Drone* drone_;
+    };
+}
+
+#endif /* _DroneController_H__ */
Index: code/trunk/src/orxonox/controllers/HumanController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/HumanController.cc	(revision 6901)
+++ code/trunk/src/orxonox/controllers/HumanController.cc	(revision 7163)
@@ -35,5 +35,4 @@
 #include "gametypes/Gametype.h"
 #include "infos/PlayerInfo.h"
-#include "overlays/Map.h"
 #include "Radar.h"
 #include "Scene.h"
@@ -116,10 +115,4 @@
     void HumanController::yaw(const Vector2& value)
     {
-        //Hack to enable mouselook in map
-        if ( Map::getSingletonPtr() && Map::getSingletonPtr()->getVisibility() && HumanController::localController_s->controllableEntity_->isInMouseLook() )
-        {
-            Map::getSingletonPtr()->rotateYaw(value);
-            return;
-        }
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
             HumanController::localController_s->controllableEntity_->rotateYaw(value);
@@ -128,10 +121,4 @@
     void HumanController::pitch(const Vector2& value)
     {
-        //Hack to enable mouselook in map
-        if ( Map::getSingletonPtr() && Map::getSingletonPtr()->getVisibility() && HumanController::localController_s->controllableEntity_->isInMouseLook() )
-        {
-            Map::getSingletonPtr()->rotatePitch(value);
-            return;
-        }
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
             HumanController::localController_s->controllableEntity_->rotatePitch(value);
Index: code/trunk/src/orxonox/controllers/NewHumanController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/NewHumanController.cc	(revision 6901)
+++ code/trunk/src/orxonox/controllers/NewHumanController.cc	(revision 7163)
@@ -217,4 +217,9 @@
                     if (this->getControllableEntity() && (this->getControllableEntity()->isExactlyA(ClassByString("SpaceShip")) || this->getControllableEntity()->isExactlyA(ClassByString("Rocket"))))
                         this->showOverlays();
+                    else if (this->getControllableEntity() &&  this->getControllableEntity()->isExactlyA(ClassByString("FpsPlayer")))
+                    {
+                        this->showOverlays();
+                        this->hideArrows();
+                    }
 
                     this->crossHairOverlay_->setPosition(Vector2(static_cast<float>(this->currentYaw_)/2*-1+.5f-overlaySize_/2, static_cast<float>(this->currentPitch_)/2*-1+.5f-overlaySize_/2));
@@ -364,12 +369,27 @@
         Ogre::RaySceneQueryResult& result = rsq->execute();
         Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
+        WorldEntity* myWe = static_cast<WorldEntity*>(this->getControllableEntity());
 
         Ogre::RaySceneQueryResult::iterator itr;
         for (itr = result.begin(); itr != result.end(); ++itr)
         {
-            if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" && itr->distance > 500)
+//             CCOUT(0) << "testing object as target" << endl;
+            if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" /*&& itr->distance > 500*/)
             {
                 // Try to cast the user pointer
-                WorldEntity* wePtr = dynamic_cast<WorldEntity*>(Ogre::any_cast<OrxonoxClass*>(itr->movable->getUserAny()));
+                WorldEntity* wePtr;
+                try
+                {
+                    wePtr = dynamic_cast<WorldEntity*>(Ogre::any_cast<OrxonoxClass*>(itr->movable->getUserAny()));
+                }
+                catch (...)
+                {
+                    continue;
+                }
+
+                // make sure we don't shoot ourselves
+                if( wePtr==myWe )
+                    continue;
+
                 if (wePtr)
                 {
@@ -379,5 +399,5 @@
                     while (parent)
                     {
-                        if (this->targetMask_.isExcluded(parent->getIdentifier()))
+                        if (this->targetMask_.isExcluded(parent->getIdentifier()) || parent==myWe)
                         {
                             parent = parent->getParent();
@@ -430,5 +450,6 @@
             HumanController::yaw(value);
 
-        this->currentYaw_ = value.x;
+        if (this->getControllableEntity() && !this->getControllableEntity()->isExactlyA(ClassByString("FpsPlayer")))
+            this->currentYaw_ = value.x;
     }
 
@@ -439,5 +460,6 @@
             HumanController::pitch(value);
 
-        this->currentPitch_ = value.x;
+        if (this->getControllableEntity() && !this->getControllableEntity()->isExactlyA(ClassByString("FpsPlayer")))
+            this->currentPitch_ = value.x;
     }
 
@@ -579,3 +601,8 @@
         }
     }
+
+
+
+
+
 }
Index: code/trunk/src/orxonox/controllers/NewHumanController.h
===================================================================
--- code/trunk/src/orxonox/controllers/NewHumanController.h	(revision 6901)
+++ code/trunk/src/orxonox/controllers/NewHumanController.h	(revision 7163)
@@ -67,4 +67,5 @@
             virtual void doResumeControl();
 
+
         protected:
             void updateTarget();
Index: code/trunk/src/orxonox/controllers/WaypointPatrolController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/WaypointPatrolController.cc	(revision 6901)
+++ code/trunk/src/orxonox/controllers/WaypointPatrolController.cc	(revision 7163)
@@ -42,5 +42,5 @@
         RegisterObject(WaypointPatrolController);
 
-        this->team_ = 0;
+        //this->team_ = 0;
         this->alertnessradius_ = 500;
 
@@ -53,5 +53,5 @@
 
         XMLPortParam(WaypointPatrolController, "alertnessradius", setAlertnessRadius, getAlertnessRadius, xmlelement, mode).defaultValues(500.0f);
-        XMLPortParam(WaypointPatrolController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(0);
+//        XMLPortParam(WaypointPatrolController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(0);
     }
 
Index: code/trunk/src/orxonox/controllers/WaypointPatrolController.h
===================================================================
--- code/trunk/src/orxonox/controllers/WaypointPatrolController.h	(revision 6901)
+++ code/trunk/src/orxonox/controllers/WaypointPatrolController.h	(revision 7163)
@@ -46,8 +46,8 @@
             virtual void tick(float dt);
 
-            inline void setTeam(int team)
+           /* inline void setTeam(int team)
                 { this->team_ = team; }
             inline int getTeam() const
-                { return this->team_; }
+                { return this->team_; } */
 
             inline void setAlertnessRadius(float radius)
@@ -59,5 +59,5 @@
             void searchEnemy();
 
-            int team_;
+            //int team_;
             float alertnessradius_;
             Timer patrolTimer_;
Index: code/trunk/src/orxonox/gamestates/GSClient.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSClient.cc	(revision 6901)
+++ code/trunk/src/orxonox/gamestates/GSClient.cc	(revision 7163)
@@ -40,9 +40,8 @@
     DeclareGameState(GSClient, "client", false, false);
 
-    SetCommandLineArgument(ip, "127.0.0.1").information("Sever IP as string in the form #.#.#.#");
+    SetCommandLineArgument(dest, "127.0.0.1").information("Server hostname/IP (IP in the form of #.#.#.#)");
 
     GSClient::GSClient(const GameStateInfo& info)
         : GameState(info)
-        , client_(0)
     {
     }
@@ -56,21 +55,21 @@
         GameMode::setIsClient(true);
 
-        this->client_ = new Client(CommandLineParser::getValue("ip").getString(), CommandLineParser::getValue("port"));
+//         this->client_ = new Client();
+//         this->client_->setDestination(CommandLineParser::getValue("dest").getString(), CommandLineParser::getValue("port") );
 
-        if(!client_->establishConnection())
+        if( !Client::getInstance()->establishConnection() )
         {
-            delete this->client_;
             ThrowException(InitialisationFailed, "Could not establish connection with server.");
         }
 
-        client_->update(Game::getInstance().getGameClock());
+        Client::getInstance()->update(Game::getInstance().getGameClock());
     }
 
     void GSClient::deactivate()
     {
-        client_->closeConnection();
+        Client::getInstance()->closeConnection();
 
         // destroy client
-        delete this->client_;
+//         delete this->client_;
 
         GameMode::setIsClient(false);
@@ -79,5 +78,5 @@
     void GSClient::update(const Clock& time)
     {
-        client_->update(time);
+        Client::getInstance()->update(time);
     }
 }
Index: code/trunk/src/orxonox/gamestates/GSClient.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSClient.h	(revision 6901)
+++ code/trunk/src/orxonox/gamestates/GSClient.h	(revision 7163)
@@ -46,7 +46,4 @@
         void deactivate();
         void update(const Clock& time);
-
-    private:
-        Client* client_;
     };
 }
Index: code/trunk/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 6901)
+++ code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 7163)
@@ -39,6 +39,4 @@
 #include "core/Game.h"
 #include "core/GUIManager.h"
-// HACK:
-#include "overlays/Map.h"
 
 namespace orxonox
@@ -73,6 +71,5 @@
     void GSGraphics::deactivate()
     {
-        // HACK: (destroys a resource smart pointer)
-        Map::hackDestroyMap();
+
     }
 
Index: code/trunk/src/orxonox/gametypes/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/gametypes/CMakeLists.txt	(revision 6901)
+++ code/trunk/src/orxonox/gametypes/CMakeLists.txt	(revision 7163)
@@ -6,3 +6,4 @@
   UnderAttack.cc
   Asteroids.cc
+  Dynamicmatch.cc
 )
Index: code/trunk/src/orxonox/gametypes/Dynamicmatch.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/Dynamicmatch.cc	(revision 7163)
+++ code/trunk/src/orxonox/gametypes/Dynamicmatch.cc	(revision 7163)
@@ -0,0 +1,699 @@
+/*
+ *   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:
+ *      Johannes Ritz
+ *   Co-authors:
+ *      ...
+ *
+ */
+//TODO:
+//pig punkte vergeben pro Zeit!
+//killerfarbe schwarz; evtl. eigenes Raumfahrzeug;
+//Low; Codeoptimierung und Dokumentation
+
+/*
+short gaming manual:
+There are three different parties a player can belong to: victim, chaser or killer
+Every player starts as chaser. As long as there are not enough victims and killers, you can change your and other player's parties by shooting them.
+In order to win you have to earn as much points as possible:
+- as victim by escaping the chasers
+- as chaser by shooting the victim
+- as killer by killing the chasers
+
+
+What you shouldn't do is shooting at players of your own party. By doing so your score will decrease.
+P.S: If you don't want to be a victim: Get rid of your part by shooting a chaser.
+*/
+#include "Dynamicmatch.h"
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "network/Host.h"
+#include "infos/PlayerInfo.h"
+#include "worldentities/pawns/Pawn.h"
+#include "worldentities/pawns/SpaceShip.h"
+#include "core/ConfigValueIncludes.h"
+#include "interfaces/TeamColourable.h"
+#include "items/Engine.h"
+#include "tools/Timer.h"
+#include "worldentities/TeamSpawnPoint.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(Dynamicmatch);
+
+    Dynamicmatch::Dynamicmatch(BaseObject* creator) : Gametype(creator)
+    {
+        RegisterObject(Dynamicmatch);
+        this->gameTime_ = 180;
+        this->setConfigValues();
+        this->chaser=0;
+        this->piggy=1;
+        this->killer=2;
+        this->notEnoughPigs=false;
+        this->notEnoughKillers=false;
+        this->notEnoughChasers=false;
+        this->gameEnded_ =false;
+        this->timesequence_ = static_cast<int>(this->gameTime_);
+        this->friendlyfire=true;
+        this->numberOf[chaser]=0;
+        this->numberOf[piggy]=0;
+        this->numberOf[killer]=0;
+        this->tutorial=true;
+        this->pointsPerTime=0.0f;
+        this->setHUDTemplate("DynamicmatchHUD");
+    }
+
+    void Dynamicmatch::setConfigValues()
+    {
+        SetConfigValue(gameTime_, 180);
+        SetConfigValue(friendlyfire, true);
+        SetConfigValue(tutorial, true);
+        static ColourValue colours[] =
+        {
+            ColourValue(1.0f, 0.3f, 0.3f),  //chasercolour
+            ColourValue(0.3f, 0.3f, 1.0f),  //piggycolour
+            ColourValue(0.3f, 1.0f, 0.3f)   //killercolour  what about black: 0.0f, 0.0f, 0.0f
+
+        };
+        static std::vector<ColourValue> defaultcolours(colours, colours + sizeof(colours) / sizeof(ColourValue));
+
+        SetConfigValue(partyColours_, defaultcolours);
+    }
+
+    bool Dynamicmatch::allowPawnDamage(Pawn* victim, Pawn* originator)
+    {
+        //TODO: static and fading message for the "human" player's
+        if (!originator||!victim)
+            return false;
+        if (!originator->getPlayer()||!victim->getPlayer())
+            return false;
+        if (victim && victim->getPlayer()) //&& originator && originator->getPlayer() ??
+        {
+        int target= playerParty_[victim->getPlayer()];
+        int source= playerParty_[originator->getPlayer()];
+
+            //Case: Not Enough Pigs: party change (= party management)
+            if (notEnoughPigs)
+            {
+                numberOf[target]--; //decrease numberof victims's party
+                playerParty_[victim->getPlayer()]=piggy; //victim's new party: pig
+                setPlayerColour(victim->getPlayer()); //victim's new colour
+                numberOf[piggy]++; //party switch: number of players is not affected (decrease and increase)
+
+                    if(tutorial) //announce party switch
+                    {
+                         std::map<PlayerInfo*, Player>::iterator it2 = this->players_.find(victim->getPlayer());
+                         if (it2 != this->players_.end())
+                         {
+                              this->gtinfo_->sendStaticMessage("Either hide or shoot a chaser.",it2->first->getClientID(), partyColours_[chaser]);
+                              this->gtinfo_->sendFadingMessage("You're now a victim.",it2->first->getClientID());
+                         }
+                    }
+                    if (notEnoughKillers) //reward the originator
+                    {
+                        numberOf[source]--; //decrease numberof originator's party
+                        playerParty_[originator->getPlayer()]=killer; //originator's new party: killer
+                        setPlayerColour(originator->getPlayer()); //originator's new colour
+                        numberOf[killer]++;
+
+                        if(tutorial) //announce party switch
+                        {
+                             std::map<PlayerInfo*, Player>::iterator it3 = this->players_.find(originator->getPlayer());
+                             if (it3 != this->players_.end())
+                             {
+                                  this->gtinfo_->sendStaticMessage("Take the chasers down.",it3->first->getClientID(), partyColours_[chaser]);
+                                  this->gtinfo_->sendFadingMessage("You're now a killer.",it3->first->getClientID());
+                             }
+                        }
+                    }
+                evaluatePlayerParties(); //check if the party change has to trigger futher party changes
+
+                //Give new pig boost
+                SpaceShip* spaceship = dynamic_cast<SpaceShip*>(victim);
+                if (spaceship && spaceship->getEngine())
+                {
+                    spaceship->getEngine()->setSpeedFactor(5);
+                    WeakPtr<Engine>* ptr = new WeakPtr<Engine>(spaceship->getEngine());
+                    new Timer(10, false, &createExecutor(createFunctor(&Dynamicmatch::resetSpeedFactor, this))->setDefaultValue(0, ptr), true);
+                }
+            }
+
+            //Case: notEnoughKillers: party change
+            else if (notEnoughKillers)
+            {
+                numberOf[source]--; //decrease numberof originator's party
+                playerParty_[originator->getPlayer()]=killer; //originator's new party: killer
+                setPlayerColour(originator->getPlayer()); //originator colour
+                numberOf[killer]++; //party switch: number of players is not affected (decrease and increase)
+
+
+                if(tutorial) //announce party switch
+                {
+                     std::map<PlayerInfo*, Player>::iterator it3 = this->players_.find(originator->getPlayer());
+                     if (it3 != this->players_.end())
+                     {
+                          this->gtinfo_->sendStaticMessage("Take the chasers down.",it3->first->getClientID(),partyColours_[chaser]);
+                          this->gtinfo_->sendFadingMessage("You're now a killer.",it3->first->getClientID());
+                     }
+                }
+                evaluatePlayerParties(); //check if the party change has to trigger futher party changes
+            }
+            //Case: notEnoughChasers: party change
+            else if (notEnoughChasers)
+            {
+                numberOf[target]--; //decrease numberof victims's party
+                playerParty_[victim->getPlayer()]=chaser; //victim's new party: chaser
+                setPlayerColour(victim->getPlayer()); //victim colour
+                numberOf[chaser]++; //party switch: number of players is not affected (decrease and increase)
+
+                if(tutorial) //announce party switch
+                {
+                     std::map<PlayerInfo*, Player>::iterator it3 = this->players_.find(originator->getPlayer());
+                     if (it3 != this->players_.end())
+                     {
+                          if (numberOf[killer]>0)
+                              this->gtinfo_->sendStaticMessage("Shoot at the victim as often as possible. Defend yourself against the killers.",it3->first->getClientID(),partyColours_[piggy]);
+
+                          else
+                              this->gtinfo_->sendStaticMessage("Shoot at the victim as often as possible.",it3->first->getClientID(),partyColours_[piggy]);
+                          this->gtinfo_->sendFadingMessage("You're now a chaser.",it3->first->getClientID());
+                     }
+                }
+                evaluatePlayerParties(); //check if the party change has to trigger futher party changes
+            }
+
+            //Case: chaser vs. killer
+            else if ((source == killer && target == chaser)||(target == killer && source == chaser ))
+            {
+                return true;
+            }
+
+            //Case: a chaser hits piggy
+            else if ((source==chaser)&&(target==piggy))
+            {
+                std::map<PlayerInfo*, Player>::iterator it = this->players_.find(originator->getPlayer());
+                if (it != this->players_.end())
+                    {
+                        it->second.frags_++;
+                    }
+            }
+            //Case: piggy hits chaser
+            else if (source==piggy&&target==chaser)
+            {
+                //partyswitch: victim bcomes piggy and the originator(piggy) becomes chaser
+                playerParty_[victim->getPlayer()]=piggy;
+                playerParty_[originator->getPlayer()]=chaser;
+
+                //party switch -> colour switch
+                setPlayerColour(victim->getPlayer()); //victim colour
+                setPlayerColour(originator->getPlayer());//originator colour
+
+                //Announce pary switch
+                if(tutorial)
+                {
+                     std::map<PlayerInfo*, Player>::iterator it = this->players_.find(originator->getPlayer());
+                     if (it != this->players_.end())
+                     {
+                          if (numberOf[killer]>0)
+                              this->gtinfo_->sendStaticMessage("Shoot at the victim as often as possible. Defend yourself against the killers.",it->first->getClientID(), partyColours_[piggy]);
+                          else
+                              this->gtinfo_->sendStaticMessage("Shoot at the victim as often as possible.",it->first->getClientID(),partyColours_[piggy]);
+                          this->gtinfo_->sendFadingMessage("You're now a chaser.",it->first->getClientID());
+                     }
+                     std::map<PlayerInfo*, Player>::iterator it2 = this->players_.find(victim->getPlayer());
+                     if (it2 != this->players_.end())
+                     {
+                          this->gtinfo_->sendStaticMessage("Either hide or shoot a chaser.",it2->first->getClientID(),partyColours_[chaser]);
+                          this->gtinfo_->sendFadingMessage("You're now a victim.",it2->first->getClientID());
+                     }
+                }
+                //Give new pig boost
+                SpaceShip* spaceship = dynamic_cast<SpaceShip*>(victim);
+                if (spaceship && spaceship->getEngine())
+                {
+                    spaceship->getEngine()->setSpeedFactor(5);
+                    WeakPtr<Engine>* ptr = new WeakPtr<Engine>(spaceship->getEngine());
+                    new Timer(10, false, &createExecutor(createFunctor(&Dynamicmatch::resetSpeedFactor, this))->setDefaultValue(0, ptr), true);
+                }
+
+            }
+            // killer vs piggy
+            else if (source==killer &&target==piggy) //party and colour switch
+            {
+            playerParty_[victim->getPlayer()]=killer;
+            playerParty_[originator->getPlayer()]=piggy;
+
+            setPlayerColour(victim->getPlayer()); //victim colour
+            setPlayerColour(originator->getPlayer()); //originator colour
+
+            if(tutorial) //Announce pary switch
+            {
+                 std::map<PlayerInfo*, Player>::iterator it = this->players_.find(originator->getPlayer());
+                 if (it != this->players_.end())
+                 {
+                      this->gtinfo_->sendStaticMessage("Either hide or shoot a chaser.",it->first->getClientID(),partyColours_[chaser]);
+                      this->gtinfo_->sendFadingMessage("You're now a victim.",it->first->getClientID());
+                 }
+                 std::map<PlayerInfo*, Player>::iterator it2 = this->players_.find(victim->getPlayer());
+                 if (it2 != this->players_.end())
+                 {
+                      this->gtinfo_->sendStaticMessage("Take the chasers down.",it2->first->getClientID(),partyColours_[chaser]);
+                      this->gtinfo_->sendFadingMessage("You're now a killer.",it2->first->getClientID());
+                 }
+                }
+            }
+            //Case: friendly fire
+            else if (friendlyfire && (source == target))
+            {
+                std::map<PlayerInfo*, Player>::iterator it = this->players_.find(originator->getPlayer());
+                if (it != this->players_.end())
+                    {
+                        it->second.frags_--;
+                    }
+            }
+        }// from far far away not to be removed!
+        return false; //default: no damage
+    }
+
+
+
+    bool Dynamicmatch::allowPawnDeath(Pawn* victim, Pawn* originator)
+    {
+        //killers can kill chasers and killers can be killed by chasers
+        if ((playerParty_[originator->getPlayer()] == killer && playerParty_[victim->getPlayer()] == chaser)||(playerParty_[victim->getPlayer()] == killer &&
+        playerParty_[originator->getPlayer()] == chaser ))
+        {
+            if (playerParty_[originator->getPlayer()] == killer) //reward the killer
+            {
+                std::map<PlayerInfo*, Player>::iterator it = this->players_.find(originator->getPlayer());
+                if (it != this->players_.end())
+                {
+                    it->second.frags_+=20; //value must be tested
+                }
+            }
+        return true;
+        }
+        else return false;
+    }
+
+    void Dynamicmatch::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn) //set party + colouring
+    {
+        if (!player)
+            return;
+
+        Dynamicmatch::setPlayerColour(player); //Set playercolour
+        evaluatePlayerParties();
+    }
+
+    void Dynamicmatch::playerEntered(PlayerInfo* player) //standardfunction
+    {
+        if (!player)// only for safety
+            return;
+        playerParty_[player]=chaser; //Set playerparty
+        numberOf[chaser]++;
+        Gametype::playerEntered(player);
+        const std::string& message6 = player->getName() + " entered the game";
+        COUT(0) << message6 << std::endl;
+        Host::Broadcast(message6);
+    }
+
+    bool Dynamicmatch::playerLeft(PlayerInfo* player) //standardfunction
+    {
+        bool valid_player = Gametype::playerLeft(player);
+        if (valid_player)
+        {
+            switch (playerParty_[player])
+            {
+            case 0: numberOf[chaser]--; break;
+            case 1: numberOf[piggy]--; break;
+            case 2: numberOf[killer]--; break;
+            }
+            const std::string& message = player->getName() + " left the game";
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+            //remove player from map
+            playerParty_.erase (player);
+            //adjust player parties
+            evaluatePlayerParties();
+        }
+
+        return valid_player;
+    }
+
+
+    void Dynamicmatch::tick(float dt)
+    {
+        SUPER(Dynamicmatch, tick, dt);
+
+        if (this->hasStarted() && !gameEnded_)
+        {   pointsPerTime =pointsPerTime + dt;
+            gameTime_ = gameTime_ - dt;
+            if (pointsPerTime > 2.0f)//hard coded!! should be changed
+            {
+                pointsPerTime=0.0f;
+                rewardPig();
+            }
+            if (gameTime_<= 0)
+            {
+                this->gameEnded_ = true;
+                this->end();
+            }
+            if ( gameTime_ <= timesequence_ && gameTime_ > 0)
+            {
+                const std::string& message = multi_cast<std::string>(timesequence_) + " seconds left!";
+
+                this->gtinfo_->sendAnnounceMessage(message);
+
+                if (timesequence_ >= 30 && timesequence_ <= 60)
+                {
+                    timesequence_ = timesequence_ - 10;
+                }
+                else if (timesequence_ <= 30)
+                {
+                    timesequence_ = timesequence_ - 5;
+                }
+                else
+                {
+                    timesequence_ = timesequence_ - 30;
+                }
+            }
+        }
+    }
+
+    void Dynamicmatch::rewardPig()
+    {
+        for (std::map< PlayerInfo*, int >::iterator it = this->playerParty_.begin(); it != this->playerParty_.end(); ++it) //durch alle Spieler iterieren und alle piggys finden
+        {
+            if (it->second==piggy)
+            {
+                 //Spieler mit der Pig-party frags++
+                 std::map<PlayerInfo*, Player>::iterator it2 = this->players_.find(it->first);// still not sure if right syntax
+                 if (it2 != this->players_.end())
+                 {
+                     it2->second.frags_++;
+                 }
+            }
+        }
+    }
+    void Dynamicmatch::setPlayerColour(PlayerInfo* player) // sets a player's colour
+    {
+        std::map<PlayerInfo*, int>::const_iterator it_player = this->playerParty_.find(player);
+        Pawn* pawn = dynamic_cast<Pawn*>(player->getControllableEntity());
+            if (pawn)
+            {
+                pawn->setRadarObjectColour(this->partyColours_[it_player->second]);
+
+                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 = orxonox_cast<TeamColourable*>(*it);
+                        tc->setTeamColour(this->partyColours_[it_player->second]);
+                    }
+                }
+            }
+    }
+
+    void Dynamicmatch::evaluatePlayerParties() //manages the notEnough booleans (here the percentage of special players is implemented)
+    {
+        //pigs: 1 + every 6th player is a pig
+        if ( (1+this->getNumberOfPlayers()/6) > numberOf[piggy])
+        {
+            notEnoughPigs=true;
+            if (tutorial) // Announce selectionphase
+            {
+             for (std::map<PlayerInfo*, int>::iterator it = this->playerParty_.begin(); it != this->playerParty_.end(); ++it)
+                {
+                    if (!it->first)//in order to catch nullpointer
+                        continue;
+                    if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                        continue;
+                    this->gtinfo_->sendStaticMessage("Selection phase: Shoot at everything that moves.",it->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f));
+                }
+            }
+        }
+        else
+        {
+             notEnoughPigs=false;
+             if(tutorial&&(!notEnoughKillers)&&(!notEnoughChasers)) //Selection phase over
+             {
+                  for (std::map<PlayerInfo*, int>::iterator it = this->playerParty_.begin(); it != this->playerParty_.end(); ++it)
+                  {
+                       if (!it->first)//in order to catch nullpointer
+                           continue;
+                       if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                           continue;
+                       else if (it->second==chaser)
+                       {
+                           if (numberOf[killer]>0)
+                               this->gtinfo_->sendStaticMessage("Shoot at the victim as often as possible. Defend yourself against the killers.",it->first->getClientID(),partyColours_[piggy]);
+                           else
+                               this->gtinfo_->sendStaticMessage("Shoot at the victim as often as possible.",it->first->getClientID(),partyColours_[piggy]);
+                           //this->gtinfo_->sendFadingMessage("You're now a chaser.",it->first->getClientID());
+                       }
+                       else if (it->second==piggy)
+                       {
+                           this->gtinfo_->sendStaticMessage("Either hide or shoot a chaser.",it->first->getClientID(),partyColours_[chaser]);
+                           //this->gtinfo_->sendFadingMessage("You're now a victim.",it->first->getClientID());
+                       }
+                       else if (it->second==killer)
+                       {
+                           this->gtinfo_->sendStaticMessage("Take the chasers down.",it->first->getClientID(),partyColours_[chaser]);
+                           //this->gtinfo_->sendFadingMessage("You're now a killer.",it->first->getClientID());
+                       }
+                  }
+
+             }
+        }
+        //killers: every 4th player is a killer
+        if (getNumberOfPlayers()/4 > numberOf[killer])
+        {
+            notEnoughKillers=true;
+            if (tutorial) // Announce selectionphase
+            {
+             for (std::map<PlayerInfo*, int>::iterator it = this->playerParty_.begin(); it != this->playerParty_.end(); ++it)
+                {
+                    if (!it->first)//in order to catch nullpointer
+                        continue;
+                    if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                        continue;
+                    this->gtinfo_->sendStaticMessage("Selection phase: Shoot at everything that moves.",it->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f));
+                }
+            }
+        }
+        else
+        {
+            notEnoughKillers=false;
+            if(tutorial&&(!notEnoughPigs)&&(!notEnoughChasers)) //Selection phase over
+             {
+                  for (std::map<PlayerInfo*, int>::iterator it = this->playerParty_.begin(); it != this->playerParty_.end(); ++it)
+                  {
+                       if (!it->first)
+                           continue;
+                       if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                           continue;
+                       else if (it->second==chaser)
+                       {
+                           if (numberOf[killer]>0)
+                               this->gtinfo_->sendStaticMessage("Shoot at the victim as often as possible. Defend yourself against the killers.",it->first->getClientID(),partyColours_[piggy]);
+                           else
+                               this->gtinfo_->sendStaticMessage("Shoot at the victim as often as possible.",it->first->getClientID(),partyColours_[piggy]);
+                           //this->gtinfo_->sendFadingMessage("You're now a chaser.",it->first->getClientID());
+                       }
+                       else if (it->second==piggy)
+                       {
+                           this->gtinfo_->sendStaticMessage("Either hide or shoot a chaser.",it->first->getClientID(),partyColours_[piggy]);
+                           //this->gtinfo_->sendFadingMessage("You're now a victim.",it->first->getClientID());
+                       }
+                       else if (it->second==killer)
+                       {
+                           this->gtinfo_->sendStaticMessage("Take the chasers down.",it->first->getClientID(),partyColours_[piggy]);
+                           //this->gtinfo_->sendFadingMessage("You're now a killer.",it->first->getClientID());
+                       }
+                  }
+
+             }
+
+        }
+        //chasers: there are more chasers than killers + pigs
+        if (numberOf[piggy]+numberOf[killer] > numberOf[chaser])
+        {
+            notEnoughChasers=true;
+            if (tutorial) // Announce selectionphase
+            {
+             for (std::map<PlayerInfo*, int>::iterator it = this->playerParty_.begin(); it != this->playerParty_.end(); ++it)
+                {
+                    if (!it->first)//in order to catch nullpointer
+                        continue;
+                    if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                        continue;
+                    this->gtinfo_->sendStaticMessage("Selection phase: Shoot at everything that moves.",it->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f));
+                }
+            }
+        }
+        else
+        {
+             notEnoughChasers=false;
+             if(tutorial&&(!notEnoughPigs)&&(!notEnoughKillers)) //Selection phase over
+             {
+                  for (std::map<PlayerInfo*, int>::iterator it = this->playerParty_.begin(); it != this->playerParty_.end(); ++it)
+                  {
+                       if (!it->first)
+                           continue;
+                       if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                           continue;
+                       else if (it->second==chaser)
+                       {
+                           if (numberOf[killer]>0)
+                               this->gtinfo_->sendStaticMessage("Shoot at the victim as often as possible. Defend yourself against the killers.",it->first->getClientID(),partyColours_[piggy]);
+                           else
+                               this->gtinfo_->sendStaticMessage("Shoot at the victim as often as possible.",it->first->getClientID(),partyColours_[piggy]);
+                           //this->gtinfo_->sendFadingMessage("You're now a chaser.",it->first->getClientID());
+                       }
+                       else if (it->second==piggy)
+                       {
+                           this->gtinfo_->sendStaticMessage("Either hide or shoot a chaser.",it->first->getClientID(),partyColours_[chaser]);
+                           //this->gtinfo_->sendFadingMessage("You're now a victim.",it->first->getClientID());
+                       }
+                       else if (it->second==killer)
+                       {
+                           this->gtinfo_->sendStaticMessage("Take the chasers down.",it->first->getClientID(),partyColours_[chaser]);
+                           //this->gtinfo_->sendFadingMessage("You're now a killer.",it->first->getClientID());
+                       }
+                  }
+
+             }
+        }
+    }
+
+    int Dynamicmatch::getParty(PlayerInfo* player) // helper function for ArtificialController
+    {
+        return this->playerParty_[player];
+    }
+
+    void Dynamicmatch::resetSpeedFactor(WeakPtr<Engine>* ptr)// helper function
+    {
+        if (*ptr)
+        {
+            (*ptr)->setSpeedFactor(1.0f);
+        }
+        delete ptr;
+    }
+
+    bool Dynamicmatch::playerChangedName(PlayerInfo* player) //standardfunction
+    {
+        bool valid_player = Gametype::playerChangedName(player);
+        if (valid_player)
+        {
+            const std::string& message = player->getOldName() + " changed name to " + player->getName();
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+        }
+
+        return valid_player;
+    }
+
+    void Dynamicmatch::start()
+    {
+        Gametype::start();
+        if(!tutorial)
+        {
+            std::string message("Dynamicmatch started!");
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+        }
+        else if(tutorial) // Announce selectionphase
+        {
+            for (std::map<PlayerInfo*, int>::iterator it = this->playerParty_.begin(); it != this->playerParty_.end(); ++it)
+            {
+                if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                    continue;
+                this->gtinfo_->sendStaticMessage("Selection phase: Shoot at everything that moves.",it->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f));
+            }
+        }
+    }
+
+    /*void Dynamicmatch::instructions()
+    {
+        std::string message("Earn points:\n\n\n\tIf you're red: Chase the blue player!\n\n\tIf you're blue shoot at a red player or hide.\n\n\tIf you're green: You've got the licence to kill red players!");
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+        callInstructions_.setTimer(10, false, createExecutor(createFunctor(&Dynamicmatch::furtherInstructions, this)));
+    }
+
+    void Dynamicmatch::furtherInstructions()
+    {
+        std::string message("After 3 Minutes the game is over.");
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }*/
+    void Dynamicmatch::end()
+    {
+        Gametype::end();
+
+        std::string message("Time out. Press F2 to see the points you scored.");
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+    SpawnPoint* Dynamicmatch::getBestSpawnPoint(PlayerInfo* player) const
+    {
+        int desiredTeamNr = -1;
+        std::map<PlayerInfo*, int>::const_iterator it_player = this->playerParty_.find(player);
+        if (it_player != this->playerParty_.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*>::iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); )
+        {
+            if ((*it)->isA(Class(TeamSpawnPoint)))
+            {
+                TeamSpawnPoint* tsp = orxonox_cast<TeamSpawnPoint*>(*it);
+                if (tsp && static_cast<int>(tsp->getTeamNumber()) != desiredTeamNr)//getTeamNumber!!
+                {
+                    teamSpawnPoints.erase(it++);
+                    continue;
+                }
+            }
+
+            ++it;
+        }
+
+        if (teamSpawnPoints.size() > 0)
+        {
+            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(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;
+    }
+
+}
Index: code/trunk/src/orxonox/gametypes/Dynamicmatch.h
===================================================================
--- code/trunk/src/orxonox/gametypes/Dynamicmatch.h	(revision 7163)
+++ code/trunk/src/orxonox/gametypes/Dynamicmatch.h	(revision 7163)
@@ -0,0 +1,92 @@
+/*
+ *   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:
+ *      Johannes Ritz
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Dynamicmatch_H__
+#define _Dynamicmatch_H__
+
+#include <map>
+#include <vector>
+#include "OrxonoxPrereqs.h"
+#include "Gametype.h"
+#include "tools/Timer.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Dynamicmatch : public Gametype
+    {
+        public:
+            Dynamicmatch(BaseObject* creator);
+            virtual ~Dynamicmatch() {}
+
+            bool notEnoughPigs;
+            bool notEnoughKillers;
+            bool notEnoughChasers;
+
+            //three different parties
+            int chaser;
+            int piggy;
+            int killer;
+
+            virtual void evaluatePlayerParties();
+            int getParty(PlayerInfo* player);
+            void setPlayerColour(PlayerInfo* player);//own function
+            void setConfigValues();//done
+
+            bool friendlyfire; //goal: player can switch it on/off
+            bool tutorial; //goal: new players receive messages how the new gametype works - later it can be switched off.
+
+            virtual bool allowPawnDamage(Pawn* victim, Pawn* originator = 0); //ok - score function and management of parties
+            virtual bool allowPawnDeath(Pawn* victim, Pawn* originator = 0); //ok - simple
+            virtual void start();
+            virtual void end(); //Wie geht das mit der Punkteausgabe aendern? Z.B: Persoenliche Nachricht?
+            virtual void playerEntered(PlayerInfo* player);
+            virtual void playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn);//is used to initialize the player's party and colour
+            virtual bool playerLeft(PlayerInfo* player);
+            virtual bool playerChangedName(PlayerInfo* player);//unchanged
+
+            /*virtual void instructions();
+            virtual void furtherInstructions();*/
+            virtual void rewardPig();
+            void resetSpeedFactor(WeakPtr<Engine>* ptr);
+            void tick (float dt);// used to end the game
+            SpawnPoint* getBestSpawnPoint(PlayerInfo* player) const;
+
+        protected:
+
+            std::map< PlayerInfo*, int > playerParty_; //player's parties are recorded here
+            std::vector<ColourValue> partyColours_; //aus TeamDeathmatch
+            unsigned int numberOf[3]; //array to count number of chasers, pigs, killers
+            float pointsPerTime;
+            float gameTime_;   // from UnderAttack
+            bool gameEnded_; // true if game is over
+            int timesequence_; //used for countdown
+            //Timer callInstructions_;
+    };
+}
+
+#endif /* _Dynamicmatch_H__ */
Index: code/trunk/src/orxonox/gametypes/Gametype.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/Gametype.cc	(revision 6901)
+++ code/trunk/src/orxonox/gametypes/Gametype.cc	(revision 7163)
@@ -309,7 +309,22 @@
         if (this->spawnpoints_.size() > 0)
         {
+            SpawnPoint* fallbackSpawnPoint = NULL;
             unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
             unsigned int index = 0;
+            std::set<SpawnPoint*> activeSpawnPoints = this->spawnpoints_;
             for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
+            {
+                if (index == randomspawn)
+                    fallbackSpawnPoint = (*it);
+
+                if (!(*it)->isActive())
+                    activeSpawnPoints.erase(*it);
+
+                ++index;
+            }
+
+            randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
+            index = 0;
+            for (std::set<SpawnPoint*>::const_iterator it = activeSpawnPoints.begin(); it != activeSpawnPoints.end(); ++it)
             {
                 if (index == randomspawn)
@@ -318,4 +333,6 @@
                 ++index;
             }
+
+            return fallbackSpawnPoint;
         }
         return 0;
Index: code/trunk/src/orxonox/gametypes/TeamDeathmatch.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/TeamDeathmatch.cc	(revision 6901)
+++ code/trunk/src/orxonox/gametypes/TeamDeathmatch.cc	(revision 7163)
@@ -137,8 +137,35 @@
         }
 
+        SpawnPoint* fallbackSpawnPoint = NULL;
         if (teamSpawnPoints.size() > 0)
         {
             unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(teamSpawnPoints.size())));
             unsigned int index = 0;
+            // Get random fallback spawnpoint in case there is no active SpawnPoint.
+            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); ++it)
+            {
+                if (index == randomspawn)
+                {
+                    fallbackSpawnPoint = (*it);
+                    break;
+                }
+
+                ++index;
+            }
+
+            // Remove all inactive SpawnPoints from the list.
+            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); )
+            {
+                if(!(*it)->isActive())
+                {
+                    teamSpawnPoints.erase(it++);
+                    continue;
+                }
+
+                ++it;
+            }
+
+            randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(teamSpawnPoints.size())));
+            index = 0;
             for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); ++it)
             {
@@ -148,4 +175,6 @@
                 ++index;
             }
+
+            return fallbackSpawnPoint;
         }
 
Index: code/trunk/src/orxonox/graphics/AnimatedModel.cc
===================================================================
--- code/trunk/src/orxonox/graphics/AnimatedModel.cc	(revision 7163)
+++ code/trunk/src/orxonox/graphics/AnimatedModel.cc	(revision 7163)
@@ -0,0 +1,126 @@
+/*
+ *   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:
+ *      Benjamin de Capitani
+ *
+ *
+ */
+
+#include "AnimatedModel.h"
+
+#include <OgreEntity.h>
+#include <OgreAnimationState.h>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(AnimatedModel);
+
+    AnimatedModel::AnimatedModel(BaseObject* creator) : Model(creator)
+    {
+        RegisterObject(AnimatedModel);
+    }
+
+
+    AnimatedModel::~AnimatedModel()
+    {
+        if (this->isInitialized() && this->mesh_.getEntity())
+            this->detachOgreObject(this->mesh_.getEntity());
+    }
+
+    void AnimatedModel::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(AnimatedModel, XMLPort, xmlelement, mode);
+        XMLPortParam(AnimatedModel,"anims",setAnims,getAnims, xmlelement,mode).defaultValues("");
+        XMLPortParam(AnimatedModel,"loop", setAnimLoop,getAnimLoop, xmlelement,mode).defaultValues(true);
+        XMLPortParam(AnimatedModel,"enabled", setAnimEnabled,getAnimEnabled, xmlelement,mode).defaultValues(true);
+    }
+
+
+    void AnimatedModel::changedMesh()
+    {
+        if (GameMode::showsGraphics())
+        {
+            if (this->mesh_.getEntity())
+                this->detachOgreObject(this->mesh_.getEntity());
+
+            this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
+
+            if (this->mesh_.getEntity())
+            {
+                this->attachOgreObject(this->mesh_.getEntity());
+                this->mesh_.getEntity()->setCastShadows(this->bCastShadows_);
+                this->setAnimationState(this->bAnimLoop_, this->bAnimEnabled_, this->anims_);
+                this->mesh_.setVisible(this->isVisible());
+            }
+        }
+    }
+
+    void AnimatedModel::changedAnimationState()
+    {
+        this->setAnimationState(this->bAnimLoop_, this->bAnimEnabled_, this->anims_);
+    }
+    void AnimatedModel::setAnimationState(bool loop, bool enabled, const std::string& state)
+    {
+        if(state!="")
+        {
+        if(this->mesh_.getEntity()->getAnimationState(state))
+        {
+        Ogre::AnimationState* as = this->mesh_.getEntity()->getAnimationState(state);
+        as->setLoop(loop);
+        as->setEnabled(enabled);
+        this->anims_ = state;
+        }
+        }
+    }
+
+    void AnimatedModel::setAnimLoop(bool loop)
+    {
+        this->bAnimLoop_ = loop;
+    }
+    void AnimatedModel::setAnimEnabled(bool enabled)
+    {
+        this->bAnimEnabled_ = enabled;
+    }
+    void AnimatedModel::tick(float dt)
+    {
+        if(this->mesh_.getEntity()->getAnimationState(anims_))
+        {
+// Test to change Material at runtime!
+
+//            Ogre::MaterialPtr mat = this->mesh_.getEntity()->getSubEntity(0)->getMaterial();
+//            mat->setDiffuse(0.4, 0.3, 0.1, 0.1);
+//            mat->setAmbient(0.3, 0.7, 0.8);
+//            mat->setSpecular(0.5, 0.5, 0.5, 0.1);
+//            Ogre::SceneBlendType sbt = Ogre::SBT_ADD;
+//
+//            mat->setSceneBlending(sbt);
+
+            Ogre::AnimationState* as = this->mesh_.getEntity()->getAnimationState(anims_);
+            as->addTime(dt);
+    }
+}
+}
Index: code/trunk/src/orxonox/graphics/AnimatedModel.h
===================================================================
--- code/trunk/src/orxonox/graphics/AnimatedModel.h	(revision 7163)
+++ code/trunk/src/orxonox/graphics/AnimatedModel.h	(revision 7163)
@@ -0,0 +1,76 @@
+/*
+ *   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 _AnimatedModel_H__
+#define _AnimatedModel_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "tools/interfaces/Tickable.h"
+#include "Model.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport AnimatedModel : public Model, public Tickable
+    {
+        public:
+            AnimatedModel(BaseObject* creator);
+            virtual ~AnimatedModel();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void changedAnimationState();
+            virtual void setAnimationState(bool loop, bool enabled, const std::string& state);
+            virtual void setAnimEnabled(bool enabled);
+            virtual void setAnimLoop(bool loop);
+            virtual void tick(float dt);
+            virtual void changedMesh();
+
+
+            inline void setAnims(const std::string& anims)
+                { this->anims_ = anims; this->changedAnimationState(); }
+            inline const std::string& getAnims() const
+                { return this->anims_; }
+
+            inline const std::string& getAnimationState() const
+                { return this->anims_; }
+            inline const bool&  getAnimLoop() const
+                { return this->bAnimLoop_; }
+            inline const bool&  getAnimEnabled() const
+                { return this->bAnimEnabled_; }
+
+        private:
+            std::string anims_;
+            bool bAnimEnabled_;
+            bool bAnimLoop_;
+    };
+}
+
+#endif /* _AnimatedModel_H__ */
Index: code/trunk/src/orxonox/graphics/Backlight.h
===================================================================
--- code/trunk/src/orxonox/graphics/Backlight.h	(revision 6901)
+++ code/trunk/src/orxonox/graphics/Backlight.h	(revision 7163)
@@ -45,5 +45,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             virtual void tick(float dt);
@@ -81,4 +80,5 @@
 
         private:
+            void registerVariables();
             virtual void startturnonoff();
             virtual void stopturnonoff();
Index: code/trunk/src/orxonox/graphics/Billboard.h
===================================================================
--- code/trunk/src/orxonox/graphics/Billboard.h	(revision 6901)
+++ code/trunk/src/orxonox/graphics/Billboard.h	(revision 7163)
@@ -46,5 +46,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             virtual void changedVisibility();
@@ -78,4 +77,5 @@
 
         private:
+            void registerVariables();
             void changedMaterial();
 //            void changedRotation();
Index: code/trunk/src/orxonox/graphics/BlinkingBillboard.cc
===================================================================
--- code/trunk/src/orxonox/graphics/BlinkingBillboard.cc	(revision 6901)
+++ code/trunk/src/orxonox/graphics/BlinkingBillboard.cc	(revision 7163)
@@ -66,7 +66,9 @@
     void BlinkingBillboard::registerVariables()
     {
-//        registerVariable(this->amplitude_, VariableDirection::ToClient);
-//        registerVariable(this->frequency_, VariableDirection::ToClient);
-//        registerVariable(this->phase_,     VariableDirection::ToClient);
+        unregisterVariable(this->getScale3D());
+        registerVariable(this->amplitude_,  VariableDirection::ToClient);
+        registerVariable(this->frequency_,  VariableDirection::ToClient);
+        registerVariable(this->phase_,      VariableDirection::ToClient);
+        registerVariable(this->bQuadratic_, VariableDirection::ToClient);
     }
 
@@ -75,5 +77,5 @@
         SUPER(BlinkingBillboard, tick, dt);
 
-        if (GameMode::isMaster() && this->isActive())
+        if (this->isActive())
         {
             this->time_ += dt;
Index: code/trunk/src/orxonox/graphics/BlinkingBillboard.h
===================================================================
--- code/trunk/src/orxonox/graphics/BlinkingBillboard.h	(revision 6901)
+++ code/trunk/src/orxonox/graphics/BlinkingBillboard.h	(revision 7163)
@@ -45,5 +45,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             virtual void tick(float dt);
@@ -70,4 +69,6 @@
 
         private:
+            void registerVariables();
+            
             float amplitude_;
             float frequency_;
Index: code/trunk/src/orxonox/graphics/CEGuiSample.cc
===================================================================
--- code/trunk/src/orxonox/graphics/CEGuiSample.cc	(revision 7163)
+++ code/trunk/src/orxonox/graphics/CEGuiSample.cc	(revision 7163)
@@ -0,0 +1,304 @@
+/***********************************************************************
+    filename:   CEGuiSample.cpp
+    created:    24/9/2004
+    author:     Paul D Turner
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2008 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGuiSample.h"
+
+#ifdef HAVE_CONFIG_H
+#   include "config.h"
+#endif
+#include "CEGUISamplesConfig.h"
+
+// includes for renderer selector classes
+#if defined( __WIN32__ ) || defined( _WIN32 )
+#   include "Win32CEGuiRendererSelector.h"
+#elif defined(__linux__)
+#   ifdef CEGUI_SAMPLES_USE_GTK2
+#       include "GTK2CEGuiRendererSelector.h"
+#   else
+#       include "CLICEGuiRendererSelector.h"
+#   endif
+#elif defined(__APPLE__)
+#   include "MacCEGuiRendererSelector.h"
+#endif
+
+// includes for application types
+#ifdef CEGUI_SAMPLES_USE_OGRE
+#   include "CEGuiOgreBaseApplication.h"
+#endif
+#ifdef CEGUI_SAMPLES_USE_OPENGL
+#   include "CEGuiOpenGLBaseApplication.h"
+#endif
+#ifdef CEGUI_SAMPLES_USE_IRRLICHT
+#   include "CEGuiIrrlichtBaseApplication.h"
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTFB
+#   include "CEGuiDirectFBBaseApplication.h"
+#endif
+#if defined( __WIN32__ ) || defined( _WIN32 )
+#   ifdef CEGUI_SAMPLES_USE_DIRECTX_8
+#       include "CEGuiD3D81BaseApplication.h"
+#   endif
+#   ifdef CEGUI_SAMPLES_USE_DIRECTX_9
+#       include "CEGuiD3D9BaseApplication.h"
+#   endif
+#   ifdef CEGUI_SAMPLES_USE_DIRECTX_10
+#       include "CEGuiD3D10BaseApplication.h"
+#   endif
+#endif
+// now we include the base CEGuiBaseApplication just in case someone has managed to
+// get this far without any of the renderers.  This ensures the framework will build,
+// although there will be no renderers available for selection in the samples.
+#include "CEGuiBaseApplication.h"
+
+#include "CEGUI.h"
+
+#ifdef CEGUI_WITH_XERCES
+#   include "CEGUIXercesParser.h"
+#endif
+
+// Include iostream if not on windows.
+#if defined( __WIN32__ ) || defined( _WIN32 )
+#else
+#    include <iostream>
+#endif
+
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+CEGuiSample::CEGuiSample() :
+        d_rendererSelector(0),
+        d_sampleApp(0)
+{}
+
+
+/*************************************************************************
+    Destructor
+*************************************************************************/
+CEGuiSample::~CEGuiSample()
+{
+    if (d_sampleApp)
+    {
+        d_sampleApp->cleanup();
+        delete d_sampleApp;
+    }
+
+    if (d_rendererSelector)
+    {
+        delete d_rendererSelector;
+    }
+
+}
+
+
+/*************************************************************************
+    Application entry point
+*************************************************************************/
+int CEGuiSample::run()
+{
+    try
+    {
+        if (initialise())
+            cleanup();
+    }
+    catch (CEGUI::Exception& exc)
+    {
+        outputExceptionMessage(exc.getMessage().c_str());
+    }
+    catch (std::exception& exc)
+    {
+        outputExceptionMessage(exc.what());
+    }
+    catch(...)
+    {
+        outputExceptionMessage("Unknown exception was caught!");
+    }
+
+    return 0;
+}
+
+
+/*************************************************************************
+    Initialise the sample application
+*************************************************************************/
+bool CEGuiSample::initialise()
+{
+    // Setup renderer selection dialog for Win32
+#if defined( __WIN32__ ) || defined( _WIN32 )
+    d_rendererSelector = new Win32CEGuiRendererSelector;
+
+    // enable renderer types supported for Win32
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_8
+    d_rendererSelector->setRendererAvailability(Direct3D81GuiRendererType);
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_9
+    d_rendererSelector->setRendererAvailability(Direct3D9GuiRendererType);
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_10
+    d_rendererSelector->setRendererAvailability(Direct3D10GuiRendererType);
+#endif
+
+#elif defined(__linux__)
+    // decide which method to use for renderer selection
+#   ifdef CEGUI_SAMPLES_USE_GTK2
+        d_rendererSelector = new GTK2CEGuiRendererSelector();
+#   else
+        d_rendererSelector = new CLICEGuiRendererSelector();
+#   endif
+
+#elif defined(__APPLE__)
+     d_rendererSelector = new MacCEGuiRendererSelector();
+#endif
+
+    // enable available renderer types
+#ifdef CEGUI_SAMPLES_USE_OGRE
+    d_rendererSelector->setRendererAvailability(OgreGuiRendererType);
+#endif
+#ifdef CEGUI_SAMPLES_USE_OPENGL
+    d_rendererSelector->setRendererAvailability(OpenGLGuiRendererType);
+#endif
+#ifdef CEGUI_SAMPLES_USE_IRRLICHT
+    d_rendererSelector->setRendererAvailability(IrrlichtGuiRendererType);
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTFB
+    d_rendererSelector->setRendererAvailability(DirectFBGuiRendererType);
+#endif
+
+    // get selection from user
+    if (d_rendererSelector->invokeDialog())
+    {
+        // create appropriate application type based upon users selection
+        switch(d_rendererSelector->getSelectedRendererType())
+        {
+#ifdef CEGUI_SAMPLES_USE_OGRE
+        case OgreGuiRendererType:
+            d_sampleApp = new CEGuiOgreBaseApplication();
+            break;
+#endif
+#if defined( __WIN32__ ) || defined( _WIN32 )
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_8
+        case Direct3D81GuiRendererType:
+            d_sampleApp = new CEGuiD3D81BaseApplication();
+            break;
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_9
+        case Direct3D9GuiRendererType:
+            d_sampleApp = new CEGuiD3D9BaseApplication();
+            break;
+#endif // DX9
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_10
+        case Direct3D10GuiRendererType:
+            d_sampleApp = new CEGuiD3D10BaseApplication();
+            break;
+#endif // DX10
+#endif // Win32
+#ifdef CEGUI_SAMPLES_USE_OPENGL
+        case OpenGLGuiRendererType:
+            d_sampleApp = new CEGuiOpenGLBaseApplication();
+            break;
+#endif
+#ifdef CEGUI_SAMPLES_USE_IRRLICHT
+        case IrrlichtGuiRendererType:
+            d_sampleApp = new CEGuiIrrlichtBaseApplication();
+            break;
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTFB
+        case DirectFBGuiRendererType:
+            d_sampleApp = new CEGuiDirectFBBaseApplication();
+            break;
+#endif
+
+        default:
+            throw CEGUI::GenericException("No renderer was selected!");
+            break;
+        }
+
+        // set the default resource groups to be used
+        CEGUI::Imageset::setDefaultResourceGroup("imagesets");
+        CEGUI::Font::setDefaultResourceGroup("fonts");
+        CEGUI::Scheme::setDefaultResourceGroup("schemes");
+        CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
+        CEGUI::WindowManager::setDefaultResourceGroup("layouts");
+        CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
+#ifdef CEGUI_WITH_XERCES
+        CEGUI::XercesParser::setSchemaDefaultResourceGroup("schemas");
+#endif
+
+        // execute the base application (which sets up the demo via 'this' and runs it.
+        if (d_sampleApp->execute(this))
+        {
+            // signal that app initialised and ran
+            return true;
+        }
+
+        // sample app did not initialise, delete the object.
+        delete d_sampleApp;
+        d_sampleApp = 0;
+    }
+
+    // delete renderer selector object
+    delete d_rendererSelector;
+    d_rendererSelector = 0;
+
+    // signal app did not initialise and run.
+    return false;
+}
+
+
+/*************************************************************************
+    Cleanup the sample application.
+*************************************************************************/
+void CEGuiSample::cleanup()
+{
+    if (d_sampleApp)
+    {
+        d_sampleApp->cleanup();
+        delete d_sampleApp;
+        d_sampleApp = 0;
+    }
+
+    if (d_rendererSelector)
+    {
+        delete d_rendererSelector;
+        d_rendererSelector = 0;
+    }
+
+}
+
+
+/*************************************************************************
+    Output a message to the user in some OS independant way.
+*************************************************************************/
+void CEGuiSample::outputExceptionMessage(const char* message) const
+{
+#if defined(__WIN32__) || defined(_WIN32)
+    MessageBoxA(0, message, "CEGUI - Exception", MB_OK|MB_ICONERROR);
+#else
+    std::cout << "An exception was thrown within the sample framework:" << std::endl;
+    std::cout << message << std::endl;
+#endif
+}
Index: code/trunk/src/orxonox/graphics/CEGuiSample.h
===================================================================
--- code/trunk/src/orxonox/graphics/CEGuiSample.h	(revision 7163)
+++ code/trunk/src/orxonox/graphics/CEGuiSample.h	(revision 7163)
@@ -0,0 +1,130 @@
+/***********************************************************************
+    filename:   CEGuiSample.h
+    created:    24/9/2004
+    author:     Paul D Turner
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#ifndef _CEGuiSample_h_
+#define _CEGuiSample_h_
+
+#if (defined( __WIN32__ ) || defined( _WIN32 )) && !defined (CEGUI_STATIC)
+#   ifdef CEGUISAMPLE_EXPORTS
+#       define CEGUISAMPLE_API __declspec(dllexport)
+#   else
+#       define CEGUISAMPLE_API __declspec(dllimport)
+#   endif
+#else
+#       define CEGUISAMPLE_API
+#endif
+
+
+// forward declarations
+class CEGuiBaseApplication;
+class CEGuiRendererSelector;
+
+
+/*!
+\brief
+    This is a base class that is intended to be used for all sample applications.
+    Here we take care of common things such the renderer selection and application
+    startup.
+*/
+class CEGUISAMPLE_API CEGuiSample
+{
+public:
+    /*!
+    \brief
+        Constructor.
+    */
+    CEGuiSample();
+
+
+    /*!
+    \brief
+        Destructor.
+    */
+    virtual ~CEGuiSample();
+
+
+    /*!
+    \brief
+        Application entry point.
+
+    \return
+        code to be returned by the application.
+    */
+    int run();
+
+
+    /*!
+    \brief
+        Sample specific initialisation goes here.  This method is called by the application base object created
+        as part of the initialise call.
+
+    \return
+        false if something went wrong.
+    */
+    virtual bool initialiseSample()  = 0;
+
+
+    /*!
+    \brief
+        Cleans up resources allocated in the initialiseSample call.
+    */
+    virtual void cleanupSample() = 0;
+
+
+protected:
+    /*!
+    \brief
+        Initialises the sample system, this includes asking the user for a render to use and
+        the subsequent creation of the required systems to support that renderer.
+
+    \return
+        false if anything went wrong.
+    */
+    virtual bool initialise();
+
+
+    /*!
+    \brief
+        Cleans up all resources allocated by the initialise call.
+    */
+    virtual void cleanup();
+
+
+    /*!
+    \brief
+        Output a message to the user in some OS independant way.
+    */
+    void outputExceptionMessage(const char* message) const;
+
+    /*************************************************************************
+        Data fields
+    *************************************************************************/
+    CEGuiRendererSelector*  d_rendererSelector;     //!< Points to the renderer selector object.
+    CEGuiBaseApplication*   d_sampleApp;            //!< Pointer to the base application object.
+};
+
+#endif  // end of guard _CEGuiSample_h_
Index: code/trunk/src/orxonox/graphics/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/graphics/CMakeLists.txt	(revision 6901)
+++ code/trunk/src/orxonox/graphics/CMakeLists.txt	(revision 7163)
@@ -4,5 +4,7 @@
   FadingBillboard.cc
   GlobalShader.cc
+  MeshLodInformation.cc
   Model.cc
+  AnimatedModel.cc
   ParticleEmitter.cc
   ParticleSpawner.cc
Index: code/trunk/src/orxonox/graphics/Camera.cc
===================================================================
--- code/trunk/src/orxonox/graphics/Camera.cc	(revision 6901)
+++ code/trunk/src/orxonox/graphics/Camera.cc	(revision 7163)
@@ -111,5 +111,5 @@
         SUPER(Camera, tick, dt);
 
-        if (this->bDrag_)
+        if (this->bDrag_ && this->getTimeFactor() != 0)
         {
             // this stuff here may need some adjustments
Index: code/trunk/src/orxonox/graphics/FadingBillboard.h
===================================================================
--- code/trunk/src/orxonox/graphics/FadingBillboard.h	(revision 6901)
+++ code/trunk/src/orxonox/graphics/FadingBillboard.h	(revision 7163)
@@ -46,5 +46,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             virtual void tick(float dt);
@@ -66,4 +65,5 @@
 
         protected:
+            void registerVariables();
             virtual void startturnonoff();
             virtual void stopturnonoff();
Index: code/trunk/src/orxonox/graphics/GlobalShader.h
===================================================================
--- code/trunk/src/orxonox/graphics/GlobalShader.h	(revision 6901)
+++ code/trunk/src/orxonox/graphics/GlobalShader.h	(revision 7163)
@@ -45,5 +45,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             virtual void changedVisibility();
@@ -53,4 +52,5 @@
 
         private:
+            void registerVariables();
             void changedCompositor();
 
Index: code/trunk/src/orxonox/graphics/Light.h
===================================================================
--- code/trunk/src/orxonox/graphics/Light.h	(revision 6901)
+++ code/trunk/src/orxonox/graphics/Light.h	(revision 7163)
@@ -57,5 +57,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             virtual void changedVisibility();
@@ -132,4 +131,5 @@
 
         private:
+            void registerVariables();
             void setTypeString(const std::string& type);
             std::string getTypeString() const;
Index: code/trunk/src/orxonox/graphics/MeshLodInformation.cc
===================================================================
--- code/trunk/src/orxonox/graphics/MeshLodInformation.cc	(revision 7163)
+++ code/trunk/src/orxonox/graphics/MeshLodInformation.cc	(revision 7163)
@@ -0,0 +1,85 @@
+/*
+ *   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:
+ *      Jan Bernegger
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "MeshLodInformation.h"
+
+#include <OgreEntity.h>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(MeshLodInformation);
+
+    MeshLodInformation::MeshLodInformation(BaseObject* creator)
+    : BaseObject(creator), lodLevel_(5), bEnabled_(true), numLevels_(10), reductionRate_(0.15)
+    {
+        RegisterObject(MeshLodInformation);
+    }
+
+    MeshLodInformation::~MeshLodInformation()
+    {    }
+
+    void MeshLodInformation::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(MeshLodInformation, XMLPort, xmlelement, mode);
+
+        XMLPortParam(MeshLodInformation, "mesh", setMeshSource, getMeshSource, xmlelement, mode);
+        XMLPortParam(MeshLodInformation, "lodQuality", setLodLevel, getLodLevel, xmlelement, mode);
+        XMLPortParam(MeshLodInformation, "enabled", setEnabled, getEnabled, xmlelement, mode);
+        XMLPortParam(MeshLodInformation, "numLevels", setNumLevels, getNumLevels, xmlelement, mode);
+        XMLPortParam(MeshLodInformation, "reductionRate", setReductionRate, getReductionRate, xmlelement, mode);
+    }
+
+    std::string MeshLodInformation::getMeshName()
+    {
+        return MeshLodInformation::getMeshSource();
+    }
+
+    void MeshLodInformation::setLodLevel(float lodLevel)
+    {
+        if(lodLevel>=0)
+            lodLevel_=lodLevel;
+    }
+    float MeshLodInformation::getLodLevel()
+    {
+        return lodLevel_;
+    }
+    void MeshLodInformation::setMeshSource(std::string meshSource)
+    {
+        meshSource_ = meshSource;
+    }
+    std::string MeshLodInformation::getMeshSource()
+    {
+        return meshSource_;
+    }
+
+}
Index: code/trunk/src/orxonox/graphics/MeshLodInformation.h
===================================================================
--- code/trunk/src/orxonox/graphics/MeshLodInformation.h	(revision 7163)
+++ code/trunk/src/orxonox/graphics/MeshLodInformation.h	(revision 7163)
@@ -0,0 +1,70 @@
+/*
+ *   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:
+ *      Jan Bernegger
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MeshLodInformation_H__
+#define _MeshLodInformation_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "tools/Mesh.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport MeshLodInformation : public BaseObject
+    {
+        public:
+            MeshLodInformation(BaseObject* creator);
+            virtual ~MeshLodInformation();
+
+            float getLodLevel();
+            std::string getMeshName();
+            bool getEnabled(){ return this->bEnabled_; }
+            unsigned int getNumLevels(){ return this->numLevels_; }
+            float getReductionRate(){ return this->reductionRate_; }
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+        private:
+            void setLodLevel(float lodLevel);
+            void setMeshSource(std::string meshSource);
+            void setEnabled( bool enabled ){ this->bEnabled_ = enabled; }
+            void setNumLevels( unsigned int num ){ this->numLevels_ = num; }
+            void setReductionRate( float rate ){ this->reductionRate_ = rate; }
+            std::string getMeshSource();
+            std::string meshSource_;
+            float lodLevel_;
+            bool bEnabled_;
+            unsigned int numLevels_;
+            float reductionRate_;
+
+    };
+}
+
+#endif /* _MeshLodInformation_H__ */
Index: code/trunk/src/orxonox/graphics/Model.cc
===================================================================
--- code/trunk/src/orxonox/graphics/Model.cc	(revision 6901)
+++ code/trunk/src/orxonox/graphics/Model.cc	(revision 7163)
@@ -35,4 +35,6 @@
 #include "core/XMLPort.h"
 #include "Scene.h"
+#include "graphics/MeshLodInformation.h"
+#include "Level.h"
 
 namespace orxonox
@@ -40,9 +42,8 @@
     CreateFactory(Model);
 
-    Model::Model(BaseObject* creator) : StaticEntity(creator)
+    Model::Model(BaseObject* creator) :
+        StaticEntity(creator), bCastShadows_(true), lodLevel_(5), bLodEnabled_(true), numLodLevels_(10), lodReductionRate_(.15)
     {
         RegisterObject(Model);
-
-        this->bCastShadows_ = true;
 
         this->registerVariables();
@@ -59,4 +60,6 @@
         SUPER(Model, XMLPort, xmlelement, mode);
 
+        XMLPortParam(Model, "lodLevel", setLodLevel, getLodLevel, xmlelement, mode);
+
         XMLPortParam(Model, "mesh", setMeshSource, getMeshSource, xmlelement, mode);
         XMLPortParam(Model, "shadow", setCastShadows, getCastShadows, xmlelement, mode).defaultValues(true);
@@ -67,4 +70,14 @@
         registerVariable(this->meshSrc_,    VariableDirection::ToClient, new NetworkCallback<Model>(this, &Model::changedMesh));
         registerVariable(this->bCastShadows_, VariableDirection::ToClient, new NetworkCallback<Model>(this, &Model::changedShadows));
+    }
+
+    float Model::getBiggestScale(Vector3 scale3d)
+    {
+        float scaleFactor = scale3d.x;
+        if(scale3d.y>scaleFactor)
+            scaleFactor = scale3d.y;
+        if(scale3d.z>scaleFactor)
+            scaleFactor = scale3d.z;
+        return scaleFactor;
     }
 
@@ -83,4 +96,86 @@
                 this->mesh_.getEntity()->setCastShadows(this->bCastShadows_);
                 this->mesh_.setVisible(this->isVisible());
+
+
+                //LOD
+                if( this->mesh_.getEntity()->getMesh()->getNumLodLevels()==1 )
+                {
+                    Level* level = this->getLevel();
+
+                    assert( level != 0 );
+
+                    MeshLodInformation* lodInfo = level->getLodInfo(this->meshSrc_);
+                    if( lodInfo )
+                    {
+                        setLodLevel(lodInfo->getLodLevel());
+                        this->bLodEnabled_ = lodInfo->getEnabled();
+                        this->numLodLevels_ = lodInfo->getNumLevels();
+                        this->lodReductionRate_ = lodInfo->getReductionRate();
+                    }
+                    if( this->numLodLevels_>10 )
+                    {
+                        CCOUT(2) << "More than 10 LoD levels requested. Creating only 10." << endl;
+                        this->numLodLevels_ = 10;
+                    }
+                    if( this->bLodEnabled_ )
+                    {
+                        float volume = this->mesh_.getEntity()->getBoundingBox().volume();
+    //                     float scaleFactor = 1;
+
+    //                     BaseObject* creatorPtr = this;
+    //
+    //                     while(creatorPtr!=NULL&&orxonox_cast<WorldEntity*>(creatorPtr))
+    //                     {
+    //                         scaleFactor *= getBiggestScale(((WorldEntity*) creatorPtr)->getScale3D());
+    //                         creatorPtr = creatorPtr->getCreator();
+    //                     }
+    //                     COUT(0) << "name: " << this->meshSrc_ << "scaleFactor: " << scaleFactor << ", volume: " << volume << endl;
+
+                        COUT(4) << "Setting lodLevel for " << this->meshSrc_<< " with lodLevel_: " << this->lodLevel_ <<" and volume: "<< volume << ":" << std::endl;
+
+#if OGRE_VERSION >= 0x010700
+                        Ogre::Mesh::LodValueList distList;
+#else
+                        Ogre::Mesh::LodDistanceList distList;
+#endif
+
+                        if( lodLevel_>0 )
+                        {
+    //                         float factor = scaleFactor*5/lodLevel_;
+                            float factor = pow(volume, 2.0f / 3.0f) * 15.0f / lodLevel_;
+
+                            COUT(4) << "LodLevel set with factor: " << factor << endl;
+
+                            distList.push_back(70.0f*factor);
+                            distList.push_back(140.0f*factor);
+                            distList.push_back(170.0f*factor);
+                            distList.push_back(200.0f*factor);
+                            distList.push_back(230.0f*factor);
+                            distList.push_back(250.0f*factor);
+                            distList.push_back(270.0f*factor);
+                            distList.push_back(290.0f*factor);
+                            distList.push_back(310.0f*factor);
+                            distList.push_back(330.0f*factor);
+                            while(distList.size()>this->numLodLevels_)
+                                distList.pop_back();
+
+
+                            //Generiert LOD-Levels
+                            this->mesh_.getEntity()->getMesh()->generateLodLevels(distList, Ogre::ProgressiveMesh::VRQ_PROPORTIONAL, this->lodReductionRate_);
+                        }
+                        else
+                        {
+                            std::string what;
+                            if(lodLevel_>5)
+                                what = ">5";
+                            else
+                                what = "<0";
+
+                            COUT(4)<<"LodLevel not set because lodLevel("<<lodLevel_<<") was "<<what<<"." << endl;
+                        }
+                    }
+                    else
+                        COUT(4) << "LodLevel for " << this->meshSrc_ << " not set because is disabled." << endl;
+                }
             }
         }
Index: code/trunk/src/orxonox/graphics/Model.h
===================================================================
--- code/trunk/src/orxonox/graphics/Model.h	(revision 6901)
+++ code/trunk/src/orxonox/graphics/Model.h	(revision 7163)
@@ -45,5 +45,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             virtual void changedVisibility();
@@ -62,11 +61,26 @@
                 { return this->bCastShadows_; }
 
-        private:
+        protected:
+            void registerVariables();
             void changedMesh();
             void changedShadows();
+
+            //LoD
+            inline void setLodLevel(float lodLevel)
+                { this->lodLevel_ =  lodLevel; }
+            inline float getLodLevel() const
+                { return this->lodLevel_; }
+            float getBiggestScale(Vector3 scale3d);
 
             std::string meshSrc_;
             Mesh mesh_;
             bool bCastShadows_;
+
+            //LoD
+            float lodLevel_;
+            bool bLodEnabled_;
+            unsigned int numLodLevels_;
+            float lodReductionRate_;
+
     };
 }
Index: code/trunk/src/orxonox/graphics/ParticleEmitter.h
===================================================================
--- code/trunk/src/orxonox/graphics/ParticleEmitter.h	(revision 6901)
+++ code/trunk/src/orxonox/graphics/ParticleEmitter.h	(revision 7163)
@@ -44,5 +44,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             virtual void changedVisibility();
@@ -74,4 +73,7 @@
             std::string        source_;
             LODParticle::Value   LOD_;
+
+        private:
+            void registerVariables();
     };
 }
Index: code/trunk/src/orxonox/infos/GametypeInfo.cc
===================================================================
--- code/trunk/src/orxonox/infos/GametypeInfo.cc	(revision 6901)
+++ code/trunk/src/orxonox/infos/GametypeInfo.cc	(revision 7163)
@@ -42,4 +42,6 @@
     registerMemberNetworkFunction(GametypeInfo, dispatchKillMessage);
     registerMemberNetworkFunction(GametypeInfo, dispatchDeathMessage);
+    registerMemberNetworkFunction(GametypeInfo, dispatchStaticMessage);
+    registerMemberNetworkFunction(GametypeInfo, dispatchFadingMessage);
 
     GametypeInfo::GametypeInfo(BaseObject* creator) : Info(creator)
@@ -110,4 +112,26 @@
     }
 
+    void GametypeInfo::sendStaticMessage(const std::string& message, unsigned int clientID, const ColourValue& colour)
+    {
+        if (GameMode::isMaster())
+        {
+            if (clientID == CLIENTID_SERVER)
+                this->dispatchStaticMessage(message, colour);
+            else
+                callMemberNetworkFunction(GametypeInfo, dispatchStaticMessage, this->getObjectID(), clientID, message, colour);
+        }
+    }
+
+    void GametypeInfo::sendFadingMessage(const std::string& message, unsigned int clientID)
+    {
+        if (GameMode::isMaster())
+        {
+            if (clientID == CLIENTID_SERVER)
+                this->dispatchFadingMessage(message);
+            else
+                callMemberNetworkFunction(GametypeInfo, dispatchFadingMessage, this->getObjectID(), clientID, message);
+        }
+    }
+
     void GametypeInfo::dispatchAnnounceMessage(const std::string& message)
     {
@@ -127,3 +151,15 @@
             it->deathmessage(this, message);
     }
+
+     void GametypeInfo::dispatchStaticMessage(const std::string& message, const ColourValue& colour)
+    {
+        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
+            it->staticmessage(this, message, colour);
+    }
+
+     void GametypeInfo::dispatchFadingMessage(const std::string& message)
+    {
+        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
+            it->fadingmessage(this, message);
+    }
 }
Index: code/trunk/src/orxonox/infos/GametypeInfo.h
===================================================================
--- code/trunk/src/orxonox/infos/GametypeInfo.h	(revision 6901)
+++ code/trunk/src/orxonox/infos/GametypeInfo.h	(revision 7163)
@@ -45,6 +45,4 @@
             virtual ~GametypeInfo();
 
-            void registerVariables();
-
             inline bool hasStarted() const
                 { return this->bStarted_; }
@@ -64,10 +62,16 @@
             void sendKillMessage(const std::string& message, unsigned int clientID);
             void sendDeathMessage(const std::string& message, unsigned int clientID);
+            void sendStaticMessage(const std::string& message, unsigned int clientID, const ColourValue& colour);
+            void sendFadingMessage(const std::string& message, unsigned int clientID);
 
             void dispatchAnnounceMessage(const std::string& message);
             void dispatchKillMessage(const std::string& message);
             void dispatchDeathMessage(const std::string& message);
+            void dispatchStaticMessage(const std::string& message,const ColourValue& colour);
+            void dispatchFadingMessage(const std::string& message);
 
         private:
+            void registerVariables();
+
             bool bStarted_;
             bool bEnded_;
Index: code/trunk/src/orxonox/infos/HumanPlayer.h
===================================================================
--- code/trunk/src/orxonox/infos/HumanPlayer.h	(revision 6901)
+++ code/trunk/src/orxonox/infos/HumanPlayer.h	(revision 7163)
@@ -43,5 +43,4 @@
             virtual ~HumanPlayer();
 
-            void registerVariables();
             void setConfigValues();
 
@@ -101,4 +100,6 @@
             std::string gametypeHudTemplate_;
             OverlayGroup* gametypeHud_;
+        private:
+            void registerVariables();
     };
 }
Index: code/trunk/src/orxonox/infos/PlayerInfo.cc
===================================================================
--- code/trunk/src/orxonox/infos/PlayerInfo.cc	(revision 6901)
+++ code/trunk/src/orxonox/infos/PlayerInfo.cc	(revision 7163)
@@ -177,5 +177,5 @@
             return;
 
-//         assert( this->temporaryControllableEntity_==0 );
+        assert( this->oldControllableEntity_==0 );
 
         this->oldControllableEntity_ = this->controllableEntity_;
@@ -184,4 +184,5 @@
 
         entity->setPlayer(this);
+        entity->setController(this->controller_);
 
         if (this->controller_)
@@ -222,4 +223,6 @@
             return;
 
+        this->controllableEntity_->setController(0);
+        
         this->controllableEntity_ = this->oldControllableEntity_;
         this->controllableEntityID_ = this->controllableEntity_->getObjectID();
Index: code/trunk/src/orxonox/infos/PlayerInfo.h
===================================================================
--- code/trunk/src/orxonox/infos/PlayerInfo.h	(revision 6901)
+++ code/trunk/src/orxonox/infos/PlayerInfo.h	(revision 7163)
@@ -35,13 +35,12 @@
 #include "core/SubclassIdentifier.h"
 
-namespace orxonox
-{
-    class _OrxonoxExport PlayerInfo : public Info
-    {
+namespace orxonox // tolua_export
+{ // tolua_export
+    class _OrxonoxExport PlayerInfo // tolua_export
+        : public Info
+    { // tolua_export
         public:
             PlayerInfo(BaseObject* creator);
             virtual ~PlayerInfo();
-
-            void registerVariables();
 
             virtual void changedName();
@@ -91,4 +90,5 @@
 
         private:
+            void registerVariables();
             void networkcallback_changedcontrollableentityID();
             void networkcallback_changedgtinfoID();
@@ -103,6 +103,6 @@
             const GametypeInfo* gtinfo_;
             unsigned int gtinfoID_;
-    };
-}
+    }; // tolua_export
+} // tolua_export
 
 #endif /* _PlayerInfo_H__ */
Index: code/trunk/src/orxonox/interfaces/GametypeMessageListener.h
===================================================================
--- code/trunk/src/orxonox/interfaces/GametypeMessageListener.h	(revision 6901)
+++ code/trunk/src/orxonox/interfaces/GametypeMessageListener.h	(revision 7163)
@@ -44,4 +44,6 @@
             virtual void killmessage(const GametypeInfo* gtinfo, const std::string& message) {}
             virtual void deathmessage(const GametypeInfo* gtinfo, const std::string& message) {}
+            virtual void staticmessage(const GametypeInfo* gtinfo, const std::string& message, const ColourValue& colour) {}
+            virtual void fadingmessage(const GametypeInfo* gtinfo, const std::string& message) {}
     };
 }
Index: code/trunk/src/orxonox/interfaces/InterfaceCompilation.cc
===================================================================
--- code/trunk/src/orxonox/interfaces/InterfaceCompilation.cc	(revision 6901)
+++ code/trunk/src/orxonox/interfaces/InterfaceCompilation.cc	(revision 7163)
@@ -52,5 +52,5 @@
         RegisterRootObject(GametypeMessageListener);
     }
-    
+
     //----------------------------
     // PickupCarrier
@@ -59,14 +59,25 @@
     {
         RegisterRootObject(PickupCarrier);
-        
-        this->setCarrierName("PickupCarrier");
     }
-    
+
     PickupCarrier::~PickupCarrier()
     {
+
+    }
+
+    void PickupCarrier::preDestroy(void)
+    {
         std::set<Pickupable*>::iterator it = this->pickups_.begin();
+        std::set<Pickupable*>::iterator temp;
         while(it != this->pickups_.end())
         {
-            (*(it++))->destroy();
+            (*it)->carrierDestroyed();
+            temp = it;
+            it = this->pickups_.begin();
+            if(it == temp) // Infinite loop avoidance, in case the pickup wasn't removed from the carrier somewhere in the carrierDestroy() procedure.
+            {
+                COUT(2) << "Oops. In a PickupCarrier, while cleaning up, a Pickupable (&" << (*temp) << ") didn't unregister itself as it should have." << std::endl;;
+                it++;
+            }
         }
 
@@ -84,5 +95,5 @@
         this->isForPlayer_ = true;
     }
-    
+
     //----------------------------
     // RadarListener
Index: code/trunk/src/orxonox/interfaces/NotificationListener.h
===================================================================
--- code/trunk/src/orxonox/interfaces/NotificationListener.h	(revision 6901)
+++ code/trunk/src/orxonox/interfaces/NotificationListener.h	(revision 7163)
@@ -47,4 +47,10 @@
     class Notification;
 
+    /**
+    @brief
+        NotificationListener interface.
+    @author
+        Fabian 'x3n' Landau
+    */
     class _OrxonoxExport NotificationListener : virtual public OrxonoxClass
     {
Index: code/trunk/src/orxonox/interfaces/PickupCarrier.h
===================================================================
--- code/trunk/src/orxonox/interfaces/PickupCarrier.h	(revision 6901)
+++ code/trunk/src/orxonox/interfaces/PickupCarrier.h	(revision 7163)
@@ -45,6 +45,6 @@
 #include "core/OrxonoxClass.h"
 
-namespace orxonox // tolua_export
-{ // tolua_export
+namespace orxonox
+{
 
     //! Forward-declarations.
@@ -54,4 +54,5 @@
     class InvisiblePickup;
     class MetaPickup;
+    class DronePickup;
     class SpeedPickup;
 
@@ -62,15 +63,15 @@
         Damian 'Mozork' Frick
     */
-    class _OrxonoxExport PickupCarrier  // tolua_export
-        : virtual public OrxonoxClass
-    { // tolua_export
+    class _OrxonoxExport PickupCarrier : virtual public OrxonoxClass
+    {
         //! So that the different Pickupables have full access to their PickupCarrier.
         friend class Pickupable;
         friend class PickupManager;
-        //! Friends. 
+        //! Friends.
         friend class Pickup;
         friend class HealthPickup;
         friend class InvisiblePickup;
         friend class MetaPickup;
+        friend class DronePickup;
         friend class SpeedPickup;
 
@@ -78,37 +79,5 @@
             PickupCarrier(); //!< Constructor.
             virtual ~PickupCarrier(); //!< Destructor.
-
-            /**
-            @brief Can be called to pick up a Pickupable.
-            @param pickup A pointer to the Pickupable.
-            @return Returns true if the Pickupable was picked up, false if not.
-            */
-            bool pickup(Pickupable* pickup)
-                {
-                    bool pickedUp = this->pickups_.insert(pickup).second;
-                    if(pickedUp)
-                    {
-                        COUT(4) << "Picked up Pickupable " << pickup->getIdentifier()->getName() << "(&" << pickup << ")." << std::endl;
-                        pickup->pickedUp(this);
-                    }
-                    return pickedUp;
-                }
-
-            /**
-            @brief Can be called to drop a Pickupable.
-            @param pickup A pointer to the Pickupable.
-            @param drop If the Pickupable should just be removed from the PickupCarrier without further action, this can be set to false. true is default.
-            @return Returns true if the Pickupable has been dropped, false if not.
-            */
-            bool drop(Pickupable* pickup, bool drop = true)
-                {
-                    bool dropped = this->pickups_.erase(pickup) == 1;
-                    if(dropped && drop)
-                    {
-                        COUT(4) << "Dropping Pickupable " << pickup->getIdentifier()->getName() << "(&" << pickup << ")." << std::endl;
-                        pickup->dropped();
-                    }
-                    return dropped;
-                }
+            void preDestroy(void);
 
             /**
@@ -169,12 +138,6 @@
             */
             virtual const Vector3& getCarrierPosition(void) = 0;
-            
-            /**
-            @brief Get the name of this PickupCarrier.
-            @return Returns the name as a string.
-            */
-            const std::string& getCarrierName(void) { return this->carrierName_; } // tolua_export
-            
-        protected:        
+
+        protected:
             /**
             @brief Get all direct children of this PickupSpawner.
@@ -197,68 +160,32 @@
             std::set<Pickupable*>& getPickups(void)
                 { return this->pickups_; }
-                
-            /**
-            @brief Set the name of this PickupCarrier.
-                   The name needs to be set in the constructor of every class inheriting from PickupCarrier, by calling setCarrierName().
-            @param name The name to be set.
-            */
-            void setCarrierName(const std::string& name)
-                { this->carrierName_ = name; }
-        
+
         private:
             std::set<Pickupable*> pickups_; //!< The list of Pickupables carried by this PickupCarrier.
-            std::string carrierName_; //!< The name of the PickupCarrier, as displayed in the PickupInventory.
-            
+
             /**
-            @brief Get the number of carrier children this PickupCarrier has.
-            @return Returns the number of carrier children.
+            @brief Adds a Pickupable to the list of pickups that are carried by this PickupCarrier.
+            @param pickup A pointer to the pickup to be added.
+            @return Returns true if successfull, false if the Pickupable was already present.
             */
-            unsigned int getNumCarrierChildren(void)
+            bool addPickup(Pickupable* pickup)
                 {
-                    std::vector<PickupCarrier*>* list = this->getCarrierChildren();
-                    unsigned int size = list->size();
-                    delete list;
-                    return size;
+                    COUT(4) << "Adding Pickupable (&" << pickup << ") to PickupCarrier (&" << this << ")" << std::endl;
+                    return this->pickups_.insert(pickup).second;
                 }
-            
+
             /**
-            @brief Get the index-th child of this PickupCarrier.
-            @param index The index of the child to return.
-            @return Returns the index-th child.
+            @brief Removes a Pickupable from the list of pickups that are carried by thsi PickupCarrier.
+            @param pickup A pointer to the pickup to be removed.
+            @return Returns true if successfull, false if the Pickupable was not present in the list.
             */
-            PickupCarrier* getCarrierChild(unsigned int index)
+            bool removePickup(Pickupable* pickup)
                 {
-                    std::vector<PickupCarrier*>* list = this->getCarrierChildren();
-                    if(list->size() < index)
-                        return NULL;
-                    PickupCarrier* carrier = (*list)[index];
-                    delete list;
-                    return carrier;
+                    COUT(4) << "Removing Pickupable (&" << pickup << ") from PickupCarrier (&" << this << ")" << std::endl;
+                    return this->pickups_.erase(pickup) == 1;
                 }
-            
-            /**
-            @brief Get the number of Pickupables this PickupCarrier carries.
-            @return returns the number of pickups.
-            */
-            unsigned int getNumPickups(void)
-                { return this->pickups_.size(); }
-            
-            /**
-            @brief Get the index-th Pickupable of this PickupCarrier.
-            @param index The index of the Pickupable to return.
-            @return Returns the index-th pickup.
-            */
-            Pickupable* getPickup(unsigned int index)
-                {
-                    std::set<Pickupable*>::iterator it;
-                    for(it = this->pickups_.begin(); index != 0 && it != this->pickups_.end(); it++)
-                        index--;
-                    if(it == this->pickups_.end())
-                        return NULL;
-                    return *it;
-                }
-            
-    }; // tolua_export
-} // tolua_export
+
+    };
+}
 
 #endif /* _PickupCarrier_H__ */
Index: code/trunk/src/orxonox/interfaces/Pickupable.cc
===================================================================
--- code/trunk/src/orxonox/interfaces/Pickupable.cc	(revision 6901)
+++ code/trunk/src/orxonox/interfaces/Pickupable.cc	(revision 7163)
@@ -34,12 +34,17 @@
 #include "Pickupable.h"
 
+#include "core/LuaState.h"
+#include "core/GUIManager.h"
 #include "core/Identifier.h"
 #include "core/CoreIncludes.h"
+#include "util/Convert.h"
+#include "infos/PlayerInfo.h"
 #include "pickup/PickupIdentifier.h"
+#include "worldentities/pawns/Pawn.h"
 #include "PickupCarrier.h"
 
 namespace orxonox
 {
-    
+
     /**
     @brief
@@ -47,31 +52,59 @@
     */
     Pickupable::Pickupable() : pickupIdentifier_(NULL), used_(false), pickedUp_(false)
-    {        
+    {
         RegisterRootObject(Pickupable);
-        
+
         this->carrier_ = NULL;
-        
+
         this->pickupIdentifier_ = new PickupIdentifier(this);
-    }
-    
-    /**
-    @brief
-        Destructor. 
+        this->beingDestroyed_ = false;
+        this->enabled_ = true;
+    }
+
+    /**
+    @brief
+        Destructor.
     */
     Pickupable::~Pickupable()
     {
-        if(this->isUsed())
-            this->setUsed(false);
-        
-        if(this->isPickedUp() && this->getCarrier() != NULL)
-        {
-            this->getCarrier()->drop(this, false);
-            this->setCarrier(NULL);
-        }
-        
+        COUT(4) << "Pickupable (" << this->getIdentifier()->getName() << ") (&" << this << ") destroyed." << std::endl;
         if(this->pickupIdentifier_ != NULL)
             this->pickupIdentifier_->destroy();
     }
-    
+
+    /**
+    @brief
+        A method that is called by OrxonoxClass::destroy() before the object is actually destroyed.
+    */
+    void Pickupable::preDestroy(void)
+    {
+        this->beingDestroyed_ = true;
+
+        if(this->isPickedUp())
+            this->drop(false); // Drops the pickup without creating a PickupSpawner.
+    }
+
+    /**
+    @brief
+        Is called internally within the pickup module to destroy pickups.
+    */
+    void Pickupable::destroy(void)
+    {
+        this->destroyPickup();
+    }
+
+    /**
+    @brief
+        Destroys a Pickupable.
+        If the Pickupable is already in the process of being destroyed a warning is displayed and this method is skipped.
+    */
+    void Pickupable::destroyPickup(void)
+    {
+        if(!this->beingDestroyed_)
+            this->OrxonoxClass::destroy();
+        else
+            COUT(2) << this->getIdentifier()->getName() << " may be unsafe. " << std::endl;
+    }
+
     /**
     @brief
@@ -84,14 +117,19 @@
     bool Pickupable::setUsed(bool used)
     {
-        if(this->used_ == used)
-            return false;
-        
+        if(this->used_ == used || !this->isPickedUp()) // If either the used status of the Pickupable doesn't change or it isn't picked up.
+            return false;
+
+        if((!this->isUsable() && used) || (!this->isUnusable() && !used)) // If either the Pickupable is requested to be used but it is not usable or the Pickupable is requested to be unused, while it is not unusable.
+            return false;
+
         COUT(4) << "Pickupable (&" << this << ") set to used " << used << "." << std::endl;
-        
+
         this->used_ = used;
         this->changedUsed();
-        return true;
-    }
-    
+
+        GUIManager::getInstance().getLuaState()->doString("PickupInventory.update()");
+        return true;
+    }
+
     /**
     @brief
@@ -106,7 +144,8 @@
         if(carrier == NULL)
             return false;
+
         return this->isTarget(carrier->getIdentifier());
     }
-    
+
     /**
     @brief
@@ -125,7 +164,8 @@
                 return true;
         }
+
         return false;
     }
-        
+
     /**
     @brief
@@ -140,5 +180,5 @@
         return this->addTarget(target->getIdentifier());
     }
-    
+
     /**
     @brief
@@ -153,30 +193,67 @@
         if(this->isTarget(target)) //!< If the input target is already present in the list of targets.
             return false;
-        
+
         COUT(4) << "Target " << target->getName() << " added to Pickupable (&" << this << ")." << std::endl;
         this->targets_.push_back(target);
         return true;
     }
-    
-    /**
-    @brief  
-        Sets the Pickupable to picked up.
-        This method will be called by the PickupCarrier picking the Pickupable up.
+
+    /**
+    @brief
+        Can be called to pick up a Pickupable.
     @param carrier
-        The PickupCarrier that picked the Pickupable up.
-    @return
-        Returns false if, for some reason, the pickup could not be picked up, e.g. it was picked up already.
-    */
-    bool Pickupable::pickedUp(PickupCarrier* carrier)
-    {
-        if(this->isPickedUp()) //!< If the Pickupable is already picked up.
-            return false;
+        A pointer to the PickupCarrier that picks up the Pickupable.
+    @return
+        Returns true if the Pickupable was picked up, false if not.
+    */
+    bool Pickupable::pickup(PickupCarrier* carrier)
+    {
+        if(carrier == NULL || this->isPickedUp()) //!< If carrier is NULL or the Pickupable is already picked up.
+            return false;
+
+        if(!this->setCarrier(carrier))
+        {
+            COUT(3) << "A Pickupable (&" << this << ") was trying to be added to a PickupCarrier, but was already present." << std::endl;
+            return false;
+        }
         
+        this->setPickedUp(true);
         COUT(4) << "Pickupable (&" << this << ") got picked up by a PickupCarrier (&" << carrier << ")." << std::endl;
-        this->setCarrier(carrier);
-        this->setPickedUp(true);
-        return true;
-    }
-    
+        return true;
+    }
+
+    /**
+    @brief
+        Can be called to drop a Pickupable.
+    @param createSpawner
+        If true a spawner is to be created for the dropped Pickupable. True is default.
+    @return
+        Returns true if the Pickupable has been dropped, false if not.
+    */
+    bool Pickupable::drop(bool createSpawner)
+    {
+        if(!this->isPickedUp()) // If the Pickupable is not picked up.
+            return false;
+
+        assert(this->getCarrier()); // The Carrier cannot be NULL at this point.
+        if(!this->getCarrier()->removePickup(this)) //TODO Shouldn't this be a little later?
+            COUT(2) << "Pickupable (&" << this << ", " << this->getIdentifier()->getName() << ") is being dropped, but it was not present in the PickupCarriers list of pickups." << std::endl;
+
+        COUT(4) << "Pickupable (&" << this << ") got dropped up by a PickupCarrier (&" << this->getCarrier() << ")." << std::endl;
+        this->setUsed(false);
+        this->setPickedUp(false);
+
+        bool created = false;
+        if(createSpawner)
+            created = this->createSpawner();
+
+        this->setCarrier(NULL);
+
+        if(!created && createSpawner) // If a PickupSpawner should have been created but wasn't.
+            this->destroy();
+
+        return true;
+    }
+
     /**
     @brief
@@ -189,14 +266,17 @@
     bool Pickupable::setPickedUp(bool pickedUp)
     {
-        if(this->pickedUp_ == pickedUp)
-            return false;
-        
+        if(this->pickedUp_ == pickedUp) // If the picked up status has not changed.
+            return false;
+
         COUT(4) << "Pickupable (&" << this << ") set to pickedUp " << pickedUp << "." << std::endl;
-        
+
         this->pickedUp_ = pickedUp;
+        if(!pickedUp) // if the Pickupable has been dropped it unregisters itself with its PickupCarrier.
+            this->getCarrier()->removePickup(this);
         this->changedPickedUp();
-        return true;
-    }
-        
+        GUIManager::getInstance().getLuaState()->doString("PickupInventory.update()");
+        return true;
+    }
+
     /**
     @brief
@@ -204,11 +284,21 @@
     @param carrier
         Sets the input PickupCarrier as the carrier of the pickup.
-    */
-    inline bool Pickupable::setCarrier(PickupCarrier* carrier)
-    {
-        if(this->carrier_ == carrier)
-            return false;
-        
+    @param tell
+        If true (default) the pickup is added to the list of pickups in the PickupCarrier.
+    @return
+        Returns true if successful, false if not.
+    */
+    bool Pickupable::setCarrier(orxonox::PickupCarrier* carrier, bool tell)
+    {
+        if(this->carrier_ == carrier) // If the PickupCarrier doesn't change.
+            return false;
+
         COUT(4) << "Pickupable (&" << this << ") changed Carrier (& " << carrier << ")." << std::endl;
+
+        if(carrier != NULL && tell)
+        {
+            if(!carrier->addPickup(this))
+                return false;
+        }
         
         this->carrier_ = carrier;
@@ -216,33 +306,14 @@
         return true;
     }
-    
-    /**
-    @brief 
-        Sets the Pickupable to not picked up or dropped.
-        This method will be called by the PickupCarrier dropping the Pickupable.
-    @return
-        Returns false if the pickup could not be dropped.
-    */
-    bool Pickupable::dropped(void)
-    {
-        if(!this->isPickedUp()) //!< If the Pickupable is not picked up.
-            return false;
-        
-        COUT(4) << "Pickupable (&" << this << ") got dropped up by a PickupCarrier (&" << this->getCarrier() << ")." << std::endl;
-        this->setUsed(false);
-        this->setPickedUp(false);
-        
-        bool created = this->createSpawner();
-        
-        this->setCarrier(NULL);
-        
-        if(!created)
-        {
-            this->destroy();
-        }
-        
-        return true;
-    }
-    
+
+    /**
+    @brief
+        Is called by the PickupCarrier when it is being destroyed.
+    */
+    void Pickupable::carrierDestroyed(void)
+    {
+        this->destroy();
+    }
+
     /**
     @brief
@@ -255,11 +326,11 @@
         OrxonoxClass* item = NULL;
         this->clone(item);
-        
+
         Pickupable* pickup = dynamic_cast<Pickupable*>(item);
-        
+
         COUT(4) << "Pickupable (&" << this << ") cloned. Clone is new Pickupable (&" << pickup << ")." << std::endl;
         return pickup;
     }
-    
+
     /**
     @brief
@@ -273,4 +344,20 @@
         SUPER(Pickupable, clone, item);
     }
-    
+
+    /**
+    @brief
+        Method to transcribe a Pickupable as a Rewardable to the player.
+    @param player
+        A pointer to the PlayerInfo, do whatever you want with it.
+    @return
+        Return true if successful.
+    */
+    bool Pickupable::reward(PlayerInfo* player)
+    {
+        ControllableEntity* entity = player->getControllableEntity();
+        Pawn* pawn = static_cast<Pawn*>(entity);
+        PickupCarrier* carrier = static_cast<PickupCarrier*>(pawn);
+        return this->pickup(carrier);
+    }
+
 }
Index: code/trunk/src/orxonox/interfaces/Pickupable.h
===================================================================
--- code/trunk/src/orxonox/interfaces/Pickupable.h	(revision 6901)
+++ code/trunk/src/orxonox/interfaces/Pickupable.h	(revision 7163)
@@ -41,8 +41,9 @@
 
 #include "core/OrxonoxClass.h"
+#include "Rewardable.h"
 
-namespace orxonox
-{
-    
+namespace orxonox // tolua_export
+{ // tolua_export
+
     /**
     @brief
@@ -51,18 +52,18 @@
         Damian 'Mozork' Frick
     */
-    class _OrxonoxExport Pickupable : virtual public OrxonoxClass
-    {
+    class _OrxonoxExport Pickupable  // tolua_export
+        : virtual public OrxonoxClass, public Rewardable
+    {  // tolua_export
         protected:
             Pickupable(); //!< Default constructor.
-        
+
         public:
             virtual ~Pickupable(); //!< Default destructor.
-            
+
             /**
             @brief Get whether the pickup is currently in use or not.
             @return Returns true if the pickup is currently in use.
             */
-            inline bool isUsed(void)
-                { return this->used_; }
+            inline bool isUsed(void) { return this->used_; }  // tolua_export
             /**
             @brief  Should be called when the pickup has transited from used to unused or the other way around.
@@ -70,5 +71,5 @@
             */
             virtual void changedUsed(void) {}
-            
+
             /**
             @brief Get the carrier of the pickup.
@@ -82,11 +83,10 @@
             */
             virtual void changedCarrier(void) {}
-            
+
             /**
             @brief Returns whether the Pickupable is currently picked up.
             @return Returns true if the Pickupable is currently picked up, false if not.
             */
-            inline bool isPickedUp(void)
-                { return this->pickedUp_; }
+            inline bool isPickedUp(void) { return this->pickedUp_; }  // tolua_export
             /**
             @brief  Should be called when the pickup has transited from picked up to dropped or the other way around.
@@ -94,16 +94,36 @@
             */
             virtual void changedPickedUp(void) {}
+
+            /**
+            @brief Returns whether the Pickupable can be used.
+            @return Returns true if it can be used.
+            */
+            inline bool isUsable(void) { return this->enabled_; } // tolua_export
             
-            bool pickedUp(PickupCarrier* carrier); //!< Sets the Pickupable to picked up.
-            bool dropped(void); //!< Sets the Pickupable to not picked up or dropped.
-            
+            /**
+            @brief Returns whether the Pickupable can be unused.
+            @return Returns true if it can be unused.
+            */
+            inline bool isUnusable(void) { return this->enabled_; } // tolua_export
+
+            /**
+            @brief Returns whether the Pickupable is enabled.
+                   Once a Pickupable is disabled it cannot be enabled again. A Pickupable that is disabled can neither be used nor unused.
+            @return Returns true if the Pickupable is enabled.
+            */
+            inline bool isEnabled(void)
+                { return this->enabled_; }
+
+            bool pickup(PickupCarrier* carrier); //!< Can be called to pick up a Pickupable.
+            bool drop(bool createSpawner = true); //!< Can be called to drop a Pickupable.
+
             virtual bool isTarget(PickupCarrier* carrier) const; //!< Get whether the given PickupCarrier is a target of this pickup.
             bool isTarget(const Identifier* identifier) const; //!< Get whether a given class, represented by the input Identifier, is a target of this Pickupable.
             bool addTarget(PickupCarrier* target); //!< Add a PickupCarrier as target of this pickup.
             bool addTarget(Identifier* identifier); //!< Add a class, representetd by the input Identifier, as target of this pickup.
-            
+
             Pickupable* clone(void); //!< Creates a duplicate of the Pickupable.
             virtual void clone(OrxonoxClass*& item); //!< Creates a duplicate of the input OrxonoxClass.
-            
+
             /**
             @brief Get the PickupIdentifier of this Pickupable.
@@ -112,9 +132,15 @@
             virtual const PickupIdentifier* getPickupIdentifier(void)
                 { return this->pickupIdentifier_; }
-                
+
             bool setUsed(bool used); //!< Sets the Pickupable to used or unused, depending on the input.
             bool setPickedUp(bool pickedUp); //!< Helper method to set the Pickupable to either picked up or not picked up.
-            bool setCarrier(PickupCarrier* carrier); //!< Sets the carrier of the pickup.
-            
+            //TODO: private?
+            bool setCarrier(PickupCarrier* carrier, bool tell = true); //!< Sets the carrier of the pickup.
+
+            //TODO: private?
+            virtual void carrierDestroyed(void); //!< Is called by the PickupCarrier when it is being destroyed.
+
+            void destroy(void); //!< Is called internally within the pickup module to destroy pickups.
+
         protected:
             /**
@@ -122,5 +148,14 @@
             */
             void initializeIdentifier(void) {}
-            
+
+            virtual void preDestroy(void); //!< A method that is called by OrxonoxClass::destroy() before the object is actually destroyed.
+            virtual void destroyPickup(void); //!< Destroys a Pickupable.
+
+            /**
+            @brief Sets the Pickuapble to disabled.
+            */
+            inline void setDisabled(void)
+                { this->enabled_ = false; }
+
             /**
             @brief Facilitates the creation of a PickupSpawner upon dropping of the Pickupable.
@@ -131,21 +166,29 @@
             */
             virtual bool createSpawner(void) = 0;
-            
+
             PickupIdentifier* pickupIdentifier_; //!< The PickupIdentifier of this Pickupable.
-            
+
         private:
-            
-            bool used_; //!< Whether the pickup is currently in use or not.
-            bool pickedUp_; //!< Whether the pickup is currently picked up or not.
-            
-            PickupCarrier* carrier_; //!< The carrier of the pickup.
-            std::list<Identifier*> targets_; //!< The possible targets of this pickup.
 
-    };
-    
+            bool used_; //!< Whether the Pickupable is currently in use or not.
+            bool pickedUp_; //!< Whether the Pickupable is currently picked up or not.
+
+            bool enabled_; //!< Whether the Pickupable is enabled or not.
+
+            PickupCarrier* carrier_; //!< The PickupCarrier of the Pickupable.
+            std::list<Identifier*> targets_; //!< The possible targets of this Pickupable.
+
+            bool beingDestroyed_; //!< Is true if the Pickupable is in the process of being destroyed.
+
+        // For implementing the Rewardable interface:
+        public:
+            virtual bool reward(PlayerInfo* player); //!< Method to transcribe a Pickupable as a Rewardable to the player.
+
+    };  // tolua_export
+
     SUPER_FUNCTION(10, Pickupable, changedUsed, false);
     SUPER_FUNCTION(12, Pickupable, changedCarrier, false);
     SUPER_FUNCTION(13, Pickupable, changedPickedUp, false);
-}
+}  // tolua_export
 
 #endif /* _Pickupable_H__ */
Index: code/trunk/src/orxonox/interfaces/RadarListener.h
===================================================================
--- code/trunk/src/orxonox/interfaces/RadarListener.h	(revision 6901)
+++ code/trunk/src/orxonox/interfaces/RadarListener.h	(revision 7163)
@@ -41,5 +41,7 @@
         virtual ~RadarListener() { }
 
-        virtual void displayObject(RadarViewable* viewable, bool bIsMarked) = 0;
+        virtual void addObject(RadarViewable* viewable) = 0;
+        virtual void removeObject(RadarViewable* viewable) = 0;
+        virtual void objectChanged(RadarViewable* viewable) = 0;
         virtual float getRadarSensitivity() const = 0;
         virtual void radarTick(float dt) = 0;
Index: code/trunk/src/orxonox/interfaces/RadarViewable.cc
===================================================================
--- code/trunk/src/orxonox/interfaces/RadarViewable.cc	(revision 6901)
+++ code/trunk/src/orxonox/interfaces/RadarViewable.cc	(revision 7163)
@@ -29,15 +29,10 @@
 #include "RadarViewable.h"
 
-#include <OgreSceneManager.h>
-#include <OgreSceneNode.h>
-#include <OgreEntity.h>
-
 #include "util/StringUtils.h"
 #include "core/CoreIncludes.h"
-#include "tools/DynamicLines.h"
+#include "core/GameMode.h"
 #include "worldentities/WorldEntity.h"
 #include "Radar.h"
 #include "Scene.h"
-#include "overlays/Map.h"
 
 namespace orxonox
@@ -46,11 +41,10 @@
         @brief Constructor.
     */
-    RadarViewable::RadarViewable()
-        : MapNode_(NULL)
-        , MapEntity_(NULL)
-        , line_(NULL)
-        , LineNode_(NULL)
-        , isHumanShip_(false)
+    RadarViewable::RadarViewable(BaseObject* creator, const WorldEntity* wePtr)
+        : isHumanShip_(false)
         , bVisibility_(true)
+        , bInitialized_(false)
+        , creator_(creator)
+        , wePtr_(wePtr)
         , radarObjectCamouflage_(0.0f)
         , radarObjectShape_(Dot)
@@ -60,11 +54,10 @@
 
         this->uniqueId_=getUniqueNumberString();
-/*
-        if(Map::getSingletonPtr() && Map::getSingletonPtr()->getMapSceneManagerPtr())
+        if( GameMode::showsGraphics() )
         {
-            this->addEntity();
+            this->radar_ = this->creator_->getScene()->getRadar();
+            this->radar_->addRadarObject(this);
         }
-
-        */
+        this->bInitialized_ = true;
     }
 
@@ -72,76 +65,25 @@
     RadarViewable::~RadarViewable()
     {
-        if (this->isHumanShip_ && MapNode_)
-            MapNode_->removeAllChildren();
 
-        if (MapNode_)
-            delete MapNode_;
-
-        if (MapEntity_)
-            delete MapEntity_;
-
-        if (line_)
-            delete line_;
-
-        if (LineNode_)
-            delete LineNode_;
-    }
-
-    void RadarViewable::addMapEntity()
-    { //TODO Check shape and add accordantly
-        if( this->MapNode_ && !this->MapEntity_ && Map::getSingletonPtr() && Map::getSingletonPtr()->getMapSceneManagerPtr() )
+        if( this->bInitialized_ )
         {
-            COUT(0) << "Adding " << this->uniqueId_ << " to Map.\n";
-            this->MapEntity_ = Map::getSingletonPtr()->getMapSceneManagerPtr()->createEntity( this->uniqueId_, "drone.mesh");
-            /*this->line_ =  Map::getSingletonPtr()->getMapSceneManagerPtr()->createManualObject(this->uniqueId_ + "_l");
-            this->line_->begin("Map/line_", Ogre::RenderOperation::OT_LINE_STRIP);
-            //line_->position(0, -it->getRVWorldPosition().y, 0);
-            //this->line_->position(0, -20, 0);
-            this->line_->position(0, 0, -10); //Front Arrow
-            this->line_->position(0, 0, 0);
-
-            this->line_->end(); */
-            this->line_ = new Ogre::DynamicLines(Ogre::RenderOperation::OT_LINE_LIST);
-            this->line_->addPoint( Vector3(0,0,0) );
-            this->line_->addPoint( Vector3(0,0,0) );
-
-            this->MapNode_->attachObject( this->MapEntity_ );
-
-            this->LineNode_ = this->MapNode_->createChildSceneNode();
-            this->LineNode_->attachObject( this->line_ );
-        }
-        else
-        {
-            COUT(0) << "Unable to load " << this->uniqueId_ << " to Map.\n";
+            if( GameMode::showsGraphics() )
+            {
+                this->radar_->removeRadarObject(this);
+            }
         }
     }
 
-    void RadarViewable::updateMapPosition()
-    {
-        if( this->MapNode_ )
-        {
-            this->MapNode_->setPosition( this->getRVWorldPosition() );
-            this->MapNode_->translate( this->getRVOrientedVelocity(), static_cast<Ogre::Node::TransformSpace>(3) );
-            this->MapNode_->setOrientation( this->getWorldEntity()->getOrientation() );
-//Vector3 v = this->getRVWorldPosition();
-            //this->line_->setPoint(1, Vector3(0,v.y,0) );
-            this->line_->setPoint(1, Vector3( 0, static_cast<float>(static_cast<int>( -Map::getSingletonPtr()->movablePlane_->getDistance( this->getRVWorldPosition() ) ) ) ,0 ));
-            this->line_->update();
-            if( Map::getSingletonPtr()->playerShipNode_ )
-                this->LineNode_->setDirection( Map::getSingletonPtr()->playerShipNode_->getLocalAxes().GetColumn(1) ,Ogre::Node::TS_WORLD,Vector3::UNIT_Y);
-        }
-    }
-
-    void RadarViewable::setRadarObjectDescription(const std::string& str)
-    {
-        Radar* radar = this->getWorldEntity()->getScene()->getRadar();
-        if (radar)
-            this->radarObjectShape_ = radar->addObjectDescription(str);
-        else
-        {
-            CCOUT(2) << "Attempting to access the radar, but the radar is non existent." << std::endl;
-        }
-        this->radarObjectDescription_ = str;
-    }
+//     void RadarViewable::setRadarObjectDescription(const std::string& str)
+//     {
+//         Radar* radar = this->getWorldEntity()->getScene()->getRadar();
+//         if (radar)
+//             this->radarObjectShape_ = radar->addObjectDescription(str);
+//         else
+//         {
+//             CCOUT(2) << "Attempting to access the radar, but the radar is non existent." << std::endl;
+//         }
+//         this->radarObjectDescription_ = str;
+//     }
 
     const Vector3& RadarViewable::getRVWorldPosition() const
@@ -167,3 +109,11 @@
         }
     }
+
+    void RadarViewable::settingsChanged()
+    {
+        if( GameMode::showsGraphics() )
+        {
+            this->radar_->radarObjectChanged(this);
+        }
+    }
 }
Index: code/trunk/src/orxonox/interfaces/RadarViewable.h
===================================================================
--- code/trunk/src/orxonox/interfaces/RadarViewable.h	(revision 6901)
+++ code/trunk/src/orxonox/interfaces/RadarViewable.h	(revision 7163)
@@ -36,9 +36,11 @@
 
 #include "util/Math.h"
-#include "util/OgreForwardRefs.h"
 #include "core/OrxonoxClass.h"
+#include "core/SmartPtr.h"
 
 namespace orxonox
 {
+    class BaseObject;
+
     /**
     @brief Interface for receiving window events.
@@ -56,27 +58,45 @@
 
     public:
-        RadarViewable();
+        RadarViewable(BaseObject* creator, const WorldEntity* wePtr);
         virtual ~RadarViewable();
 
         inline void setRadarObjectCamouflage(float camouflage)
-            { this->radarObjectCamouflage_ = camouflage; }
+            {
+                if( this->radarObjectCamouflage_ != camouflage )
+                {
+                    this->radarObjectCamouflage_ = camouflage;
+                    this->settingsChanged();
+                }
+            }
         inline float getRadarObjectCamouflage() const
             { return this->radarObjectCamouflage_; }
 
         inline void setRadarObjectColour(const ColourValue& colour)
-            { this->radarObjectColour_ = colour; }
+            {
+                if(this->radarObjectColour_ != colour)
+                {
+                    this->radarObjectColour_ = colour;
+                    this->settingsChanged();
+                }
+            }
         inline const ColourValue& getRadarObjectColour() const
             { return this->radarObjectColour_; }
 
-        void setRadarObjectDescription(const std::string& str);
-        inline const std::string& getRadarObjectDescription() const
-            { return this->radarObjectDescription_; }
+//         void setRadarObjectDescription(const std::string& str);
+//         inline const std::string& getRadarObjectDescription() const
+//             { return this->radarObjectDescription_; }
 
         inline void setRadarVisibility(bool b)
-            { this->bVisibility_ = b; }
+            {
+                if(b!=this->bVisibility_)
+                {
+                    this->bVisibility_ = b;
+                    this->settingsChanged();
+                }
+            }
         inline bool getRadarVisibility() const
             { return this->bVisibility_; }
 
-        virtual const WorldEntity* getWorldEntity() const = 0;
+        virtual const WorldEntity* getWorldEntity() const{ return this->wePtr_; }
 
         const Vector3& getRVWorldPosition() const;
@@ -84,25 +104,16 @@
 
         inline void setRadarObjectShape(Shape shape)
-            { this->radarObjectShape_ = shape; }
+            {
+                if( this->radarObjectShape_ != shape )
+                {
+                    this->radarObjectShape_ = shape;
+                    this->settingsChanged();
+                }
+            }
         inline Shape getRadarObjectShape() const
             { return this->radarObjectShape_; }
+        void settingsChanged();
 
-/*
-        inline void setMapNode(Ogre::SceneNode * node)
-            { this->MapNode_ = node; }
-        inline Ogre::SceneNode * getMapNode() const
-            { return this->MapNode_; }
-        inline void setMapEntity(Ogre::Entity * ent)
-            { this->MapEntity_ = ent; }
-        inline Ogre::Entity * getMapEntity() const
-            { return this->MapEntity_; }
-*/
-        //Used for Map
-        Ogre::SceneNode * MapNode_;
-        Ogre::Entity * MapEntity_;
-        Ogre::DynamicLines* line_;
-        Ogre::SceneNode * LineNode_;
-        void addMapEntity();
-        void updateMapPosition();
+
         bool isHumanShip_;
         inline const std::string& getUniqueId()
@@ -115,9 +126,13 @@
         void validate(const WorldEntity* object) const;
         bool bVisibility_;
+        bool bInitialized_;
         //Map
         std::string uniqueId_;
+        BaseObject* creator_;
 
 
         //Radar
+        const WorldEntity* wePtr_;
+        SmartPtr<Radar> radar_;
         float radarObjectCamouflage_;
         Shape radarObjectShape_;
Index: code/trunk/src/orxonox/interfaces/Rewardable.h
===================================================================
--- code/trunk/src/orxonox/interfaces/Rewardable.h	(revision 6901)
+++ code/trunk/src/orxonox/interfaces/Rewardable.h	(revision 7163)
@@ -48,5 +48,5 @@
         Damian 'Mozork' Frick
     */
-    class _OrxonoxExport Rewardable : public OrxonoxClass
+    class _OrxonoxExport Rewardable : virtual public OrxonoxClass
     {
         public:
@@ -59,5 +59,5 @@
                 Must be implemented by every class inheriting from Rewardable.
             @param player
-                A pointer to the ControllableEntity, do whatever you want with it.
+                A pointer to the PlayerInfo, do whatever you want with it.
             @return
                 Return true if successful.
Index: code/trunk/src/orxonox/items/Engine.cc
===================================================================
--- code/trunk/src/orxonox/items/Engine.cc	(revision 6901)
+++ code/trunk/src/orxonox/items/Engine.cc	(revision 7163)
@@ -64,5 +64,4 @@
         this->boostBlur_ = 0;
 
-        this->setCarrierName("Engine");
         this->speedAdd_ = 0.0;
         this->speedMultiply_ = 1.0;
Index: code/trunk/src/orxonox/items/Engine.h
===================================================================
--- code/trunk/src/orxonox/items/Engine.h	(revision 6901)
+++ code/trunk/src/orxonox/items/Engine.h	(revision 7163)
@@ -46,5 +46,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
             void setConfigValues();
 
@@ -127,4 +126,5 @@
 
         private:
+            void registerVariables();
             void networkcallback_shipID();
 
Index: code/trunk/src/orxonox/items/MultiStateEngine.h
===================================================================
--- code/trunk/src/orxonox/items/MultiStateEngine.h	(revision 6901)
+++ code/trunk/src/orxonox/items/MultiStateEngine.h	(revision 7163)
@@ -53,5 +53,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             virtual void tick(float dt);
@@ -68,4 +67,6 @@
 
         private:
+            void registerVariables();
+
             int state_;
             int oldState_;
Index: code/trunk/src/orxonox/overlays/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/overlays/CMakeLists.txt	(revision 6901)
+++ code/trunk/src/orxonox/overlays/CMakeLists.txt	(revision 7163)
@@ -4,7 +4,6 @@
   OverlayGroup.cc
 
-COMPILATION_BEGIN OverlayCompilation.cc
+#COMPILATION_BEGIN OverlayCompilation.cc
   InGameConsole.cc
-  Map.cc
-COMPILATION_END
+#COMPILATION_END
 )
Index: code/trunk/src/orxonox/overlays/GUISheet.cc
===================================================================
--- code/trunk/src/orxonox/overlays/GUISheet.cc	(revision 6901)
+++ code/trunk/src/orxonox/overlays/GUISheet.cc	(revision 7163)
@@ -32,4 +32,5 @@
 #include "core/GUIManager.h"
 #include "core/XMLPort.h"
+#include "core/GameMode.h"
 
 namespace orxonox
Index: code/trunk/src/orxonox/overlays/Map.cc
===================================================================
--- code/trunk/src/orxonox/overlays/Map.cc	(revision 6901)
+++ 	(revision )
@@ -1,454 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Si Sun
- *
- */
-
-#include "Map.h"
-
-#include <string>
-
-#include <OgreBorderPanelOverlayElement.h>
-#include <OgreCamera.h>
-#include <OgreEntity.h>
-#include <OgreHardwarePixelBuffer.h>
-#include <OgreMaterialManager.h>
-#include <OgreMovablePlane.h>
-#include <OgreOverlay.h>
-#include <OgreOverlayContainer.h>
-#include <OgreOverlayManager.h>
-#include <OgrePass.h>
-#include <OgreRenderTexture.h>
-#include <OgreResourceGroupManager.h>
-#include <OgreRoot.h>
-#include <OgreSceneManager.h>
-#include <OgreSceneNode.h>
-#include <OgreTechnique.h>
-#include <OgreTexture.h>
-#include <OgreTextureManager.h>
-#include <OgreViewport.h>
-
-#include "util/StringUtils.h"
-#include "core/ConsoleCommand.h"
-#include "core/CoreIncludes.h"
-#include "core/XMLPort.h"
-#include "interfaces/RadarViewable.h"
-#include "Scene.h"
-#include "controllers/HumanController.h"
-#include "worldentities/CameraPosition.h"
-#include "worldentities/ControllableEntity.h"
-
- namespace orxonox
- {
-    CreateFactory(Map);
-    SetConsoleCommand(Map, openMap, true);
-    //SetConsoleCommand(Map, rotateYaw, true).setAsInputCommand();
-    //SetConsoleCommand(Map, rotatePitch, true).setAsInputCommand();
-    SetConsoleCommand(Map, Zoom, true).setAsInputCommand();
-
-
-    Map* Map::singletonMap_s = 0;
-    Ogre::SceneManager* Map::mapSceneM_s = 0;
-    Ogre::Camera* Map::Cam_ = 0;
-    Ogre::SceneNode* Map::CamNode_ = 0;
-    Ogre::MaterialPtr Map::OverlayMaterial_;// = init();
-    Ogre::Overlay* Map::overlay_ = 0;
-/*
-Ogre::MaterialPtr Map::init()
-{
-    Ogre::MaterialPtr tmp;
-    tmp.setNull();
-    return tmp;
-}
-*/
-
-    //int Map::mouseLookSpeed_ = 200;
-    //Ogre::SceneNode* Map::playerShipNode_ = 0;
-
-    const int PITCH=-30;
-    const int DISTANCE=200;
-
-    Map::Map(BaseObject* creator) : OrxonoxOverlay(creator)
-    {
-        RegisterObject(Map);
-        Map::singletonMap_s=this;
-
-        //Getting Scene Manager (Hack)
-        ObjectList<Scene>::iterator it = ObjectList<Scene>::begin();
-        this->sManager_ = it->getSceneManager();
-        if( !Map::getMapSceneManager() )
-        {
-            Map::setMapSceneManager( Ogre::Root::getSingletonPtr()->createSceneManager( Ogre::ST_GENERIC,"MapScene" ) );
-        }
-
-        this->playerShipNode_ = 0;
-        //this->sNode_ = new Ogre::SceneNode(sManager_);
-        //oManager_ = Ogre::OverlayManager::getSingletonPtr();
-        //overlay_ = oManager_->create("Map");
-        //overlay_ is member of OrxonoxOverlay
-
-        //Not Showing the map as default
-        //this->isVisible_=false;
-        //overlay_->hide();
-        this->mouseLookSpeed_ = 200;
-
-        //TestEntity
-        //Ogre::Entity * ent = mapSceneM_s->createEntity("ent", "drone.mesh");
-
-        //Map::getMapSceneManager()->getRootSceneNode()->attachObject( ent );
-        /*sNode_->setPosition(0,0,-50);
-        overlay_->add3D(sNode_);
-        */
-
-
-
-
-
-        // Alter the camera aspect ratio to match the viewport
-        //mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
-        if(!Map::Cam_)
-            Cam_ = Map::getMapSceneManager()->createCamera("ReflectCam");
-        //Cam_->setPosition(200,170, -160);
-        //Cam_->lookAt(0,0,0);
-        Cam_->setAspectRatio(1);
-        //Cam_->setRenderingDistance(0);
-        if(!Map::CamNode_)
-            CamNode_ = Map::getMapSceneManager()->getRootSceneNode()->createChildSceneNode();
-
-
-        //Create overlay material
-        if(Map::OverlayMaterial_.isNull())
-            Map::OverlayMaterial_ = this->createRenderCamera(Cam_, "RttMat");
-/*
-        Ogre::TexturePtr rttTex = Ogre::TextureManager::getSingleton().createManual("RttTex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
-
-        Ogre::RenderTexture *renderTexture = rttTex->getBuffer()->getRenderTarget();
-
-        renderTexture->addViewport(Cam_);
-        renderTexture->getViewport(0)->setClearEveryFrame(true);
-        renderTexture->getViewport(0)->setBackgroundColour(ColourValue::Black);
-        renderTexture->getViewport(0)->setOverlaysEnabled(false);
-
-        Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create("RttMat", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
-        Ogre::Technique *technique = material->createTechnique();
-        technique->createPass();
-        material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
-        material->getTechnique(0)->getPass(0)->createTextureUnitState("RttTex");
-*/
-
-
-        // create overlay
-/*
-        Ogre::Overlay* pOverlay = Ogre::OverlayManager::getSingleton().create("Overlay1");
-
-        // Create a panel with RenderToTexture texture
-        Ogre::OverlayContainer* m_pOverlayPanel = static_cast<Ogre::OverlayContainer*>(Ogre::OverlayManager::getSingleton().createOverlayElement("Panel","OverlayPanelName%d"));
-        m_pOverlayPanel->setMetricsMode(Ogre::GMM_PIXELS);
-        m_pOverlayPanel->setPosition(10, 10);
-        m_pOverlayPanel->setDimensions(500, 300);
-        // Give overlay a texture
-        m_pOverlayPanel->setMaterialName(camMat_id);
-        pOverlay->add2D(m_pOverlayPanel);
-        pOverlay->show();
-*/
-        if(!this->overlay_)
-        {
-            this->overlay_ = Ogre::OverlayManager::getSingletonPtr()->create("MapOverlay");
-            Ogre::OverlayContainer* m_pOverlayPanel = static_cast<Ogre::OverlayContainer*>(Ogre::OverlayManager::getSingleton().createOverlayElement("Panel","OverlayPanelName%d"));
-            //m_pOverlayPanel->setMetricsMode(Ogre::GMM_PIXELS);
-            //m_pOverlayPanel->setPosition(10, 10);
-            //m_pOverlayPanel->setDimensions(600, 400);
-            m_pOverlayPanel->setPosition(0.01f, 0.003f);
-            m_pOverlayPanel->setDimensions(0.5f, 0.4f);
-            // Give overlay a texture
-            m_pOverlayPanel->setMaterialName("RttMat");
-            overlay_->add2D(m_pOverlayPanel);
-
-            //Add Borders
-            Ogre::BorderPanelOverlayElement* oBorder = static_cast<Ogre::BorderPanelOverlayElement*>(Ogre::OverlayManager::getSingletonPtr()->createOverlayElement("BorderPanel", "MapBorderPanel" + getUniqueNumberString()));
-            oBorder->setBorderSize( 0.003f, 0.003f );
-            oBorder->setDimensions(0.5f, 0.4f);
-            oBorder->setBorderMaterialName("StatsBorder");
-            oBorder->setTopBorderUV(0.49f, 0.0f, 0.51f, 0.5f);
-            oBorder->setTopLeftBorderUV(0.0f, 0.0f, 0.5f, 0.5f);
-            oBorder->setTopRightBorderUV(0.5f, 0.0f, 1.0f, 0.5f);
-            oBorder->setLeftBorderUV(0.0f, 0.49f, 0.5f, 0.51f);
-            oBorder->setRightBorderUV(0.5f, 0.49f, 1.0f, 0.5f);
-            oBorder->setBottomBorderUV(0.49f, 0.5f, 0.51f, 1.0f);
-            oBorder->setBottomLeftBorderUV(0.0f, 0.5f, 0.5f, 1.0f);
-            oBorder->setBottomRightBorderUV(0.5f, 0.5f, 1.0f, 1.0f);
-            //overlay_->add2D(oBorder);
-            m_pOverlayPanel->addChild(oBorder);
-        }
-
-
-        //Not Showing the map as default
-        this->isVisible_=false;
-        overlay_->hide();
-
-        //Create plane to show gridTypeError: blimport() takes no keyword arguments
-/*        Ogre::Entity* plane_ent;
-        if(Map::getMapSceneManager()->hasEntity("MapPlane"))
-            plane_ent = Map::getMapSceneManager()->getEntity("MapPlane");
-        else
-            plane_ent = Map::getMapSceneManager()->createEntity( "MapPlane", "plane.mesh");
-*/
-        this->movablePlane_ = new Ogre::MovablePlane( Vector3::UNIT_Y, 0 );
-        this->movablePlane_->normalise();
-
-        if(!Map::getMapSceneManager()->hasEntity("MapPlane"))
-        {
-            Ogre::Entity* plane_ent = Map::getMapSceneManager()->createEntity( "MapPlane", "plane.mesh");
-            planeNode_ = Map::getMapSceneManager()->createSceneNode();
-        //Create plane for calculations
-
-
-        //Ogre::MaterialPtr plane_mat = Ogre::MaterialManager::getSingleton().create("mapgrid", "General");
-        //plane_mat->getTechnique(0)->getPass(0)->createTextureUnitState("mapgrid.tga");
-        //plane_ent->setMaterialName("mapgrid");
-            plane_ent->setMaterialName("Map/Grid");
-            planeNode_->attachObject(plane_ent);
-
-            planeNode_->scale(160,1,160);
-//        planeNode_->attachObject(movablePlane_);
-        //Ogre::Material plane_mat = Ogre::MaterialManager::getSingletonPtr()->getByName("rock");
-
-
-        //ToDo create material script
-            Ogre::MaterialPtr myManualObjectMaterial = Ogre::MaterialManager::getSingleton().create("Map/Line","General");
-            myManualObjectMaterial->setReceiveShadows(false);
-            myManualObjectMaterial->getTechnique(0)->setLightingEnabled(true);
-            myManualObjectMaterial->getTechnique(0)->getPass(0)->setDiffuse(1,1,0,0);
-            myManualObjectMaterial->getTechnique(0)->getPass(0)->setAmbient(1,1,0);
-            myManualObjectMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1,1,0);
-        }
-    }
-
-    Map::~Map()
-    {
-        this->singletonMap_s = 0;
-        //delete this->overlay_;
-        /*if (this->isInitialized())
-        {
-        //delete sManager_;
-        //delete Map::getMapSceneManager()->getRootSceneNode();
-        //delete oManager_;
-        //delete CamNode_;
-        //delete Cam_;
-        //delete mapSceneM_s;
-        //Map::getMapSceneManager()->destroyAllEntities();
-        //Map::getMapSceneManager()->destroyAllCameras();
-        delete Map::getMapSceneManager();
-        }*/
-    }
-
-    Ogre::MaterialPtr Map::createRenderCamera(Ogre::Camera * cam, const std::string& matName)
-    {
-        Ogre::TexturePtr rttTex = Ogre::TextureManager::getSingleton().createManual(matName+"_tex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
-
-        Ogre::RenderTexture *renderTexture = rttTex->getBuffer()->getRenderTarget();
-
-        renderTexture->addViewport(cam);
-        renderTexture->getViewport(0)->setClearEveryFrame(true);
-        renderTexture->getViewport(0)->setBackgroundColour(ColourValue::Black);
-        renderTexture->getViewport(0)->setOverlaysEnabled(false);
-
-        Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(matName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
-        Ogre::Technique *technique = material->createTechnique();
-        technique->createPass();
-        material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
-        material->getTechnique(0)->getPass(0)->createTextureUnitState(matName+"_tex");
-        return material;
-    }
-
-    void Map::updatePositions()
-    {
-
-//Ogre::Entity * ent;// = mapSceneM_s->createEntity("ent1", "drone.mesh");
-       for(ObjectList<orxonox::RadarViewable>::iterator it = ObjectList<orxonox::RadarViewable>::begin();
-            it!=ObjectList<orxonox::RadarViewable>::end();
-            ++it)
-        {
-            //COUT(0) << "Radar_Position: " << it->getRVWorldPosition() << std::endl;
-            //Ogre::SceneNode node = it->getMapNode();
-            //Ogre::Entity ent = it->getMapEntity();
-            if( !(it->MapNode_) )
-            {
-                it->MapNode_ = Map::getMapSceneManager()->getRootSceneNode()->createChildSceneNode( it->getRVWorldPosition() );
-                //it->MapNode_->translate( it->getRVOrientedVelocity(), Ogre::TS_WORLD );
-                /*if(it->getRadarObjectShape() == RadarViewable::Dot)
-                {
-                    //if( !(it->MapEntity_) )//check wether the entity is already attached
-                    //{
-                        //it->MapEntity_ = Map::getMapSceneManager()->createEntity( getUniqueNumberString(), "drone.mesh");
-                        //it->addEntity();
-                        //it->MapNode_->attachObject( it->MapEntity_ );
-                        //it->MapNode_->attachObject( it->line_ );
-                   // }
-                }*/
-                it->addMapEntity();
-            }
-            if(it->isHumanShip_)
-            {
-                this->movablePlane_->redefine(it->MapNode_->getLocalAxes().GetColumn(1) , it->MapNode_->getPosition());
-                if(it->isHumanShip_ && it->MapNode_ != this->playerShipNode_)
-                {
-                    this->playerShipNode_ = it->MapNode_;
-                    if(planeNode_ && this->planeNode_->getParent())
-                        this->planeNode_->getParent()->removeChild(this->planeNode_);
-                    this->playerShipNode_->addChild(this->planeNode_);
-                //Movable Plane needs to be attached direcly for calculations
-                //this->movablePlane_->detatchFromParent();
-                //this->movablePlane_->getParentSceneNode()->detachObject(this->movablePlane_);
-                //this->movablePlane_->redefine(it->MapNode_->getLocalAxes().GetColumn(1) , it->MapNode_->getPosition());
-                //it->MapNode_->attachObject(this->movablePlane_);
-                    if(planeNode_ && this->CamNode_->getParent())
-                        this->CamNode_->getParent()->removeChild(this->CamNode_);
-                    this->playerShipNode_->addChild(this->CamNode_);
-                    this->CamNode_->attachObject(this->Cam_);
-                //this->CamNodeHelper_ = this->CamNode_->createChildSceneNode();
-                //this->CamNodeHelper_->attachObject(this->Cam_);
-                    this->Cam_->setPosition(0, 0, (float)DISTANCE);
-                    this->Cam_->pitch( static_cast<Degree>((float)PITCH) );
-                    this->Cam_->lookAt(this->playerShipNode_->getPosition());
-                //this->Cam_->setAutoTracking(true, this->playerShipNode_);
-                }
-            }
-            it->updateMapPosition();
-
-
-
-
-
-
-        }
-    }
-
-
-
-    void Map::XMLPort(Element& xmlElement, XMLPort::Mode mode)
-    {
-        SUPER(Map, XMLPort, xmlElement, mode);
-    }
-
-    void Map::changedOwner()
-    {
-        SUPER(Map, changedOwner);
-        //COUT(0) << "shipptr" << this->getOwner()->getReverseCamera() << std::endl;
-
-        ControllableEntity* entity = orxonox_cast<ControllableEntity*>(this->getOwner());
-        if(entity && entity->getReverseCamera())
-        {
-            //COUT(0) << "foo";
-            entity->getReverseCamera()->attachCamera(this->Cam_);
-        }
-    }
-
-
-    void Map::toggleVisibility()
-    {
-        if (!(this->isVisible_))
-        {
-            this->overlay_->show();
-            this->isVisible_=1;
-            //set mouselook when showing map
-            if (HumanController::localController_s && HumanController::localController_s->controllableEntity_ && !HumanController::localController_s->controllableEntity_->isInMouseLook())
-            HumanController::localController_s->controllableEntity_->mouseLook();
-        }
-        else
-        {
-            this->overlay_->hide();
-            this->isVisible_=0;
-            if (HumanController::localController_s && HumanController::localController_s->controllableEntity_ && HumanController::localController_s->controllableEntity_->isInMouseLook())
-            HumanController::localController_s->controllableEntity_->mouseLook();
-        }
-    }
-
-    //Static function to toggle visibility of the map
-    void Map::openMap()
-    {
-        for(ObjectList<orxonox::Map>::iterator it = ObjectList<orxonox::Map>::begin();
-            it!=ObjectList<orxonox::Map>::end();
-            ++it)
-        {
-        //Map * m = it->getMap();
-        //COUT(0) << it->isVisible_ << std::endl;
-        it->toggleVisibility();
-        //it->updatePositions();
-        }
-    }
-
-    // HACK!
-    void Map::hackDestroyMap()
-    {
-        Map::OverlayMaterial_.setNull();
-    }
-
-    void Map::tick(float dt)
-    {
-        //Debug
-        //COUT(0) << "MovablePlane Position: " << this->movablePlane_->getParentSceneNode()->getName() << this->movablePlane_->getParentSceneNode()->getPosition() << std::endl;
-        //COUT(0) << "planeNode_ Position: " << this->planeNode_ ->getName() << this->planeNode_->getPosition() << std::endl;
-        //COUT(0) <<  "planeNode_ Parrent Position" << this->planeNode_->getParent()->getName() << this->planeNode_->getParent()->getPosition() << std::endl;
-        if( this->isVisible_ )
-            updatePositions();
-        //Cam_->roll(Degree(1));
-
-    }
-
-    void Map::rotateYaw(const Vector2& value)
-    {
-        if(!( Map::singletonMap_s && Map::singletonMap_s->CamNode_ ))
-            return;
-
-/*
-        singletonMap_s->CamNode_->setOrientation(singletonMap_s->CamNode_->getOrientation() * Quaternion( static_cast<Degree>(-value.y * singletonMap_s->mouseLookSpeed_) , singletonMap_s->playerShipNode_->getLocalAxes().GetColumn(1) ));
-
-        Map::singletonMap_s->CamNodeHelper_->setDirection(Vector3::UNIT_Y, Ogre::Node::TS_PARENT, Vector3::UNIT_Y);
-        Map::singletonMap_s->CamNodeHelper_->lookAt(Vector3(0,0,0), Ogre::Node::TS_PARENT);
-*/
-        singletonMap_s->CamNode_->yaw( static_cast<Degree>(-value.y * singletonMap_s->mouseLookSpeed_), Ogre::Node::TS_PARENT);
-    }
-
-    void Map::rotatePitch(const Vector2& value)
-    {
-        if(!( Map::singletonMap_s && Map::singletonMap_s->CamNode_ ))
-            return;
-            //singletonMap_s->Cam_->setOrientation(singletonMap_s->Cam_->getOrientation() * Quaternion( static_cast<Degree>(-value.y * singletonMap_s->mouseLookSpeed_) , Vector3::UNIT_X));
-/*        singletonMap_s->CamNode_->setOrientation(singletonMap_s->CamNode_->getOrientation() * Quaternion( static_cast<Degree>(-value.y * singletonMap_s->mouseLookSpeed_) , singletonMap_s->playerShipNode_->getLocalAxes().GetColumn(0) ));
-
-        Map::singletonMap_s->CamNodeHelper_->setDirection(Vector3::UNIT_Y, Ogre::Node::TS_PARENT, Vector3::UNIT_Y);
-        Map::singletonMap_s->CamNodeHelper_->lookAt(Vector3(0,0,0), Ogre::Node::TS_PARENT);
-*/
-        singletonMap_s->CamNode_->pitch( static_cast<Degree>(value.y * singletonMap_s->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
-
-    }
-
-    void Map::Zoom(const Vector2& value)
-    {
-        if(!( Map::singletonMap_s && Map::singletonMap_s->CamNode_ ))
-            return;
-        //COUT(0) << value.y << std::endl;
-        Map::singletonMap_s->Cam_->setPosition(0,0, Map::singletonMap_s->Cam_->getPosition().z + value.y * Map::singletonMap_s->mouseLookSpeed_ );
-    }
- }
Index: code/trunk/src/orxonox/overlays/Map.h
===================================================================
--- code/trunk/src/orxonox/overlays/Map.h	(revision 6901)
+++ 	(revision )
@@ -1,118 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Si Sun
- *
- */
-
-#ifndef _Map_H__
-#define _Map_H__
-
-#include "OrxonoxPrereqs.h"
-
-#include <OgreMaterial.h>
-
-#include "util/UtilPrereqs.h"
-#include "tools/interfaces/Tickable.h"
-#include "overlays/OrxonoxOverlay.h"
-
-namespace orxonox
-{
-    class _OrxonoxExport Map : public OrxonoxOverlay, public Tickable
-    {
-
-    public: // functions
-        Map(BaseObject* creator);
-        virtual ~Map();
-
-        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
-        virtual void tick(float dt);
-        virtual void changedOwner();
-
-        static Ogre::MaterialPtr createRenderCamera(Ogre::Camera * cam, const std::string& matName);
-
-        static void openMap();
-        // HACK!
-        static void hackDestroyMap();
-
-//Not yet implemented
-        static const int maxRange_s=1000;
-
-        static void rotateYaw(const Vector2& value);
-        static void rotatePitch(const Vector2& value);
-        static void Zoom(const Vector2& value);
-        // variables
-
-
-        bool inline getVisibility()
-            { return this->isVisible_; };
-
-        static inline Ogre::SceneManager* getMapSceneManagerPtr()
-        {
-            return Map::singletonMap_s->mapSceneM_s;
-        }
-        static inline Map* getSingletonPtr()
-        {
-            return Map::singletonMap_s;
-        }
-
-        static inline Ogre::SceneManager* getMapSceneManager()
-        {
-            return Map::mapSceneM_s;
-        }
-
-
-
-    private: // functions
-
-        void toggleVisibility();
-        void updatePositions();
-//        void changedPlayerNode();
-        static inline void setMapSceneManager( Ogre::SceneManager * sm)
-        {
-            Map::mapSceneM_s = sm;
-        }
-        //static Ogre::MaterialPtr init();
-
-    private: // variables
-        static Map* singletonMap_s;
-
-        Ogre::SceneManager* sManager_;
-        Ogre::OverlayManager * oManager_;
-
-        static Ogre::SceneManager* mapSceneM_s;
-        static Ogre::SceneNode* CamNode_;
-        static Ogre::Camera* Cam_;
-        static Ogre::MaterialPtr OverlayMaterial_;
-        static Ogre::Overlay* overlay_;
-        //Ogre::SceneNode* CamNodeHelper_;
-        Ogre::SceneNode* playerShipNode_;
-        Ogre::SceneNode* planeNode_;
-        Ogre::MovablePlane* movablePlane_;
-        int mouseLookSpeed_;
-        bool isVisible_;
-
-    friend class RadarViewable;
-    };
-}
-
-#endif /* _Map_H__ */
Index: code/trunk/src/orxonox/pickup/PickupIdentifier.cc
===================================================================
--- code/trunk/src/orxonox/pickup/PickupIdentifier.cc	(revision 6901)
+++ code/trunk/src/orxonox/pickup/PickupIdentifier.cc	(revision 7163)
@@ -39,5 +39,5 @@
 namespace orxonox
 {
-    
+
     /**
     @brief
@@ -47,16 +47,16 @@
     {
         RegisterRootObject(PickupIdentifier);
-        
+
         if(pickup == NULL)
             COUT(1) << "Error, PickupIdentifier was created without a valid Pickupable." << std::endl;
-        
+
         this->pickup_ = pickup;
     }
-    
+
     PickupIdentifier::~PickupIdentifier()
     {
 
     }
-    
+
     /**
     @brief
@@ -74,5 +74,5 @@
             COUT(1) << "Error in PickupIdentifier::compare: Input Identifier is NULL." << std::endl;
         }
-        
+
         if(identifier->pickup_ == NULL && this->pickup_ == NULL)
         {
@@ -80,5 +80,5 @@
             COUT(1) << "Error in PickupIdentifier::compare: Pickup stored by Identifier is NULL." << std::endl;
         }
-        
+
         if(identifier->pickup_ == NULL)
         {
@@ -86,5 +86,5 @@
             COUT(1) << "Error in PickupIdentifier::compare: Pickup stored by Identifier is NULL." << std::endl;
         }
-        
+
         if(this->pickup_ == NULL)
         {
@@ -92,9 +92,9 @@
             COUT(1) << "Error in PickupIdentifier::compare: Pickup stored by Identifier is NULL." << std::endl;
         }
-        
+
         //! If the classIdentifiers are not the same (meaning the PickupIdentifiers identify different classes), the obviously the two Pickupables identified by the PickupIdentifiers cannot be the same. An ordering is established through the alphabetical ordering of the respective classnames.
         if(!identifier->pickup_->getIdentifier()->isExactlyA(this->pickup_->getIdentifier()))
             return this->pickup_->getIdentifier()->getName().compare(identifier->pickup_->getIdentifier()->getName());
-        
+
         //! If the class is the same for both PickupIdentifiers we go on to check the parameters of the class.
         //! If the two have a different number of parameters then obviusly something is very wrong.
@@ -104,6 +104,6 @@
             return this->parameters_.size()-identifier->parameters_.size();
         }
-        
-        //! We iterate through all parameters and compar their values (which are strings). The first parameter is the most significant. The ordering is once again established by the alphabetical comparison of the two value strings.
+
+        //! We iterate through all parameters and compare their values (which are strings). The first parameter is the most significant. The ordering is once again established by the alphabetical comparison of the two value strings.
         for(std::map<std::string, std::string>::const_iterator it = this->parameters_.begin(); it != this->parameters_.end(); it++)
         {
@@ -117,8 +117,8 @@
                 return it->second.compare(identifier->parameters_.find(it->first)->second);
         }
-            
+
         return 0;
     }
-    
+
     /**
     @brief
@@ -134,5 +134,5 @@
     {
         COUT(4) << "PickupIdentifier " << name << ", " << value << std::endl;
-        
+
         if(!(this->parameters_.find(name) == this->parameters_.end()))
         {
@@ -140,9 +140,9 @@
             return false;
         }
-        
+
         this->parameters_[name] = value;
-        
+
         return true;
     }
-    
+
 }
Index: code/trunk/src/orxonox/pickup/PickupIdentifier.h
===================================================================
--- code/trunk/src/orxonox/pickup/PickupIdentifier.h	(revision 6901)
+++ code/trunk/src/orxonox/pickup/PickupIdentifier.h	(revision 7163)
@@ -41,9 +41,9 @@
 #include "core/Identifier.h"
 
-#include "core/OrxonoxClass.h" 
+#include "core/OrxonoxClass.h"
 
 namespace orxonox
 {
-    
+
     /**
     @brief
@@ -57,19 +57,19 @@
     class _OrxonoxExport PickupIdentifier : virtual public OrxonoxClass
     {
-        
+
         public:
             PickupIdentifier(Pickupable* pickup); //!< Constructor.
             ~PickupIdentifier(); //!< Destructor.
-            
+
             virtual int compare(const PickupIdentifier* identifier) const; //!< Compares two PickupIdentifiers and returns 0 if a == b, <0 if a < b and >0 if a > b for a.compare(b).
-            
+
             bool addParameter(std::string & name, std::string & value); //!< Add a parameter to the PickupIdentifier.
-            
+
         private:
             Pickupable* pickup_; //!< The Pickupable the PickupIdentififer is for.
             std::map<std::string, std::string> parameters_; //!< The parameters identifying the type of the pickup beyond the class.
-            
+
     };
-    
+
     /**
     @brief
@@ -81,5 +81,5 @@
             { return lhs->compare(rhs) < 0; }
     };
-    
+
 }
 
Index: code/trunk/src/orxonox/sound/BaseSound.cc
===================================================================
--- code/trunk/src/orxonox/sound/BaseSound.cc	(revision 6901)
+++ code/trunk/src/orxonox/sound/BaseSound.cc	(revision 7163)
@@ -33,4 +33,5 @@
 #include <al.h>
 
+#include "util/Math.h"
 #include "core/CoreIncludes.h"
 #include "core/GameMode.h"
@@ -248,5 +249,5 @@
         else // No source acquired so far, but might be set to playing or paused
         {
-            State state = this->state_; // save
+            State state = static_cast<State>(this->state_); // save
             if (this->isPlaying() || this->isPaused())
                 doPlay();
Index: code/trunk/src/orxonox/sound/BaseSound.h
===================================================================
--- code/trunk/src/orxonox/sound/BaseSound.h	(revision 6901)
+++ code/trunk/src/orxonox/sound/BaseSound.h	(revision 7163)
@@ -112,5 +112,5 @@
         float           volume_;
         bool            bLooping_;
-        State           state_;
+        uint8_t         state_;       // This Variable is actually of type State
         float           pitch_;
 
Index: code/trunk/src/orxonox/sound/WorldSound.cc
===================================================================
--- code/trunk/src/orxonox/sound/WorldSound.cc	(revision 6901)
+++ code/trunk/src/orxonox/sound/WorldSound.cc	(revision 7163)
@@ -58,5 +58,5 @@
         registerVariable(bLooping_, ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::loopingChanged));
         registerVariable(pitch_,    ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::pitchChanged));
-        registerVariable((int&)(BaseSound::state_), ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::stateChanged));
+        registerVariable((uint8_t&)(BaseSound::state_), ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::stateChanged));
     }
 
Index: code/trunk/src/orxonox/weaponsystem/WeaponMode.cc
===================================================================
--- code/trunk/src/orxonox/weaponsystem/WeaponMode.cc	(revision 6901)
+++ code/trunk/src/orxonox/weaponsystem/WeaponMode.cc	(revision 7163)
@@ -274,3 +274,11 @@
             return BLANKSTRING;
     }
+
+    void WeaponMode::setDefaultSoundWithVolume(const std::string& soundPath, const float soundVolume){
+        if (this->defSndWpnFire_) {
+            this->defSndWpnFire_->setSource(soundPath);
+            this->defSndWpnFire_->setVolume(soundVolume);
+        }
+    }
+
 }
Index: code/trunk/src/orxonox/weaponsystem/WeaponMode.h
===================================================================
--- code/trunk/src/orxonox/weaponsystem/WeaponMode.h	(revision 6901)
+++ code/trunk/src/orxonox/weaponsystem/WeaponMode.h	(revision 7163)
@@ -55,5 +55,5 @@
             void setDefaultSound(const std::string& soundPath);
             const std::string& getDefaultSound();
-
+            void setDefaultSoundWithVolume(const std::string& soundPath, const float soundVolume);
 
             // Munition
Index: code/trunk/src/orxonox/weaponsystem/WeaponSystem.cc
===================================================================
--- code/trunk/src/orxonox/weaponsystem/WeaponSystem.cc	(revision 6901)
+++ code/trunk/src/orxonox/weaponsystem/WeaponSystem.cc	(revision 7163)
@@ -214,5 +214,6 @@
         Weapon* weapon = 0;
         while ((weapon = wPack->getWeapon(i++)))
-            weapon->getWeaponSlot()->removeWeapon();
+            if (weapon->getWeaponSlot())
+                weapon->getWeaponSlot()->removeWeapon();
 
         // Remove all added links from the WeaponSets
Index: code/trunk/src/orxonox/worldentities/BigExplosion.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/BigExplosion.cc	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/BigExplosion.cc	(revision 7163)
@@ -101,4 +101,9 @@
         this->debrisEntity3_ = new MovableEntity(this);
         this->debrisEntity4_ = new MovableEntity(this);
+        
+        this->debrisEntity1_->setSyncMode(0);
+        this->debrisEntity2_->setSyncMode(0);
+        this->debrisEntity3_->setSyncMode(0);
+        this->debrisEntity4_->setSyncMode(0);
 
         this->debris1_ = new Model(this);
@@ -106,6 +111,12 @@
         this->debris3_ = new Model(this);
         this->debris4_ = new Model(this);
+        
+        this->debris1_->setSyncMode(0);
+        this->debris2_->setSyncMode(0);
+        this->debris3_->setSyncMode(0);
+        this->debris4_->setSyncMode(0);
 
         this->explosion_ = new StaticEntity(this);
+        this->explosion_->setSyncMode(0);
 
         this->debrisSmoke1_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
@@ -158,4 +169,5 @@
         effect->setSource("Orxonox/explosion2b");
         effect->setLifetime(4.0f);
+        effect->setSyncMode(0);
 
         ParticleSpawner* effect2 = new ParticleSpawner(this->getCreator());
@@ -163,4 +175,5 @@
         effect2->setSource("Orxonox/smoke6");
         effect2->setLifetime(4.0f);
+        effect2->setSyncMode(0);
 
         this->explosion_->attach(effect);
@@ -181,4 +194,9 @@
             MovableEntity* partEntity1 = new MovableEntity(this);
             MovableEntity* partEntity2 = new MovableEntity(this);
+            
+            part1->setSyncMode(0);
+            part2->setSyncMode(0);
+            partEntity1->setSyncMode(0);
+            partEntity2->setSyncMode(0);
 
             partEntity1->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(10,100));
Index: code/trunk/src/orxonox/worldentities/BigExplosion.h
===================================================================
--- code/trunk/src/orxonox/worldentities/BigExplosion.h	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/BigExplosion.h	(revision 7163)
@@ -45,5 +45,4 @@
 
             virtual void tick(float dt);
-            void registerVariables();
 
             inline void setLOD(LODParticle::Value level)
@@ -53,4 +52,5 @@
 
         private:
+            void registerVariables();
 
             void LODchanged();
Index: code/trunk/src/orxonox/worldentities/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/worldentities/CMakeLists.txt	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/CMakeLists.txt	(revision 7163)
@@ -5,5 +5,5 @@
   MobileEntity.cc
   ControllableEntity.cc
-
+  Drone.cc
   BigExplosion.cc
   EffectContainer.cc
Index: code/trunk/src/orxonox/worldentities/ControllableEntity.h
===================================================================
--- code/trunk/src/orxonox/worldentities/ControllableEntity.h	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/ControllableEntity.h	(revision 7163)
@@ -49,5 +49,4 @@
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
             virtual void tick(float dt);
-            void registerVariables();
             void setConfigValues();
 
@@ -137,4 +136,6 @@
             inline float getMouseLookSpeed() const
                 { return this->mouseLookSpeed_; }
+            inline CameraPosition* getCurrentCameraPosition()
+                { return this->currentCameraPosition_; }
 
             inline Controller* getXMLController() const
@@ -162,5 +163,8 @@
                 { this->hudtemplate_ = name; }
 
+            Ogre::SceneNode* cameraPositionRootNode_;
+
         private:
+            void registerVariables();
             void setXMLController(Controller* controller);
 
@@ -208,5 +212,4 @@
             bool bMouseLook_;
             float mouseLookSpeed_;
-            Ogre::SceneNode* cameraPositionRootNode_;
             std::list<SmartPtr<CameraPosition> > cameraPositions_;
             CameraPosition* currentCameraPosition_;
Index: code/trunk/src/orxonox/worldentities/Drone.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/Drone.cc	(revision 7163)
+++ code/trunk/src/orxonox/worldentities/Drone.cc	(revision 7163)
@@ -0,0 +1,178 @@
+/*
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ */
+
+
+#include "Drone.h"
+
+#include "core/XMLPort.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+
+namespace orxonox
+{
+    CreateFactory(Drone);
+    /**
+    @brief
+        Constructor. Registers the object and initializes some default values.
+    */
+    Drone::Drone(BaseObject* creator) : Pawn(creator)
+    {
+        RegisterObject(Drone);
+
+        this->myController_ = 0;
+
+        this->localLinearAcceleration_.setValue(0, 0, 0);
+        this->localAngularAcceleration_.setValue(0, 0, 0);
+        this->setRadarVisibility(false);
+        this->setCollisionType(WorldEntity::Dynamic);
+
+        myController_ = new DroneController(static_cast<BaseObject*>(this)); //!< Creates a new controller and passes our this pointer to it as creator.
+        myController_->setDrone(this);
+
+        this->setController(myController_);
+    }
+
+    /**
+    @brief
+        Destructor. Destroys controller, if present.
+    */
+    Drone::~Drone()
+    {
+        if( this->isInitialized() && this->myController_ )
+            this->myController_->destroy();
+    }
+
+    /**
+    @brief
+        Method for creating a Drone through XML.
+    */
+    void Drone::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Drone, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Drone, "primaryThrust_", setPrimaryThrust, getPrimaryThrust, xmlelement, mode);
+        XMLPortParam(Drone, "auxilaryThrust_", setAuxilaryThrust, getAuxilaryThrust, xmlelement, mode);
+        XMLPortParam(Drone, "rotationThrust_", setRotationThrust, getRotationThrust, xmlelement, mode);
+        XMLPortParam(Drone, "maxDistanceToOwner_", setMaxDistanceToOwner, getMaxDistanceToOwner, xmlelement, mode);
+        XMLPortParam(Drone, "minDistanceToOwner_", setMinDistanceToOwner, getMinDistanceToOwner, xmlelement, mode);
+        XMLPortParam(Drone, "maxShootingRange_", setMaxShootingRange, getMaxShootingRange, xmlelement, mode);
+    }
+
+
+    /**
+    @brief
+        Defines which actions the Drone has to take in each tick.
+    @param dt
+        The length of the tick.
+    */
+    void Drone::tick(float dt)
+    {
+        SUPER(Drone, tick, dt);
+
+        //if (this->hasLocalController())
+        //{
+            this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() * getMass() * this->auxilaryThrust_);
+            this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() * getMass() * this->auxilaryThrust_);
+            if (this->localLinearAcceleration_.z() > 0)
+              this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->auxilaryThrust_);
+            else
+              this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->primaryThrust_);
+            this->physicalBody_->applyCentralForce(physicalBody_->getWorldTransform().getBasis() * this->localLinearAcceleration_);
+            this->localLinearAcceleration_.setValue(0, 0, 0);
+
+            this->localAngularAcceleration_ *= this->getLocalInertia() * this->rotationThrust_;
+            this->physicalBody_->applyTorque(physicalBody_->getWorldTransform().getBasis() * this->localAngularAcceleration_);
+            this->localAngularAcceleration_.setValue(0, 0, 0);
+        //}
+    }
+
+    /**
+    @brief
+        Moves the Drone in the negative z-direction (Front/Back) by an amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the movement.
+    */
+    void Drone::moveFrontBack(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() - value.x);
+    }
+
+    /**
+    @brief
+        Moves the Drone in the x-direction (Right/Left) by an amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the movement.
+    */
+    void Drone::moveRightLeft(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() + value.x);
+    }
+
+    /**
+    @brief
+        Moves the Drone in the y-direction (Up/Down) by an amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the movement.
+    */
+    void Drone::moveUpDown(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() + value.x);
+    }
+
+    /**
+    @brief
+        Rotates the Drone around the y-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void Drone::rotateYaw(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setY(this->localAngularAcceleration_.y() + value.x);
+    }
+
+    /**
+    @brief
+        Rotates the Drone around the x-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void Drone::rotatePitch(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setX(this->localAngularAcceleration_.x() + value.x);
+    }
+
+    /**
+    @brief
+        Rotates the Drone around the z-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void Drone::rotateRoll(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setZ(this->localAngularAcceleration_.z() + value.x);
+    }
+
+}
Index: code/trunk/src/orxonox/worldentities/Drone.h
===================================================================
--- code/trunk/src/orxonox/worldentities/Drone.h	(revision 7163)
+++ code/trunk/src/orxonox/worldentities/Drone.h	(revision 7163)
@@ -0,0 +1,152 @@
+/*
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Drone_H__
+#define _Drone_H__
+
+#include "OrxonoxPrereqs.h"
+#include "worldentities/pawns/Pawn.h"
+#include "controllers/DroneController.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        Drone, that is made to move upon a specified pattern.
+        This class was constructed for the PPS tutorial.
+    @author
+        Oli Scheuss
+    */
+    class _OrxonoxExport Drone : public Pawn
+    {
+        public:
+            Drone(BaseObject* creator);
+            virtual ~Drone();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a Drone through XML.
+            virtual void tick(float dt); //!< Defines which actions the Drone has to take in each tick.
+
+
+            virtual void moveFrontBack(const Vector2& value);
+            virtual void moveRightLeft(const Vector2& value);
+            virtual void moveUpDown(const Vector2& value);
+
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
+
+            /**
+            @brief Moves the Drone in the Front/Back-direction by the specifed amount.
+            @param value  The amount by which the drone is to be moved.
+            */
+            inline void moveFrontBack(float value)
+            { this->moveFrontBack(Vector2(value, 0)); }
+            /**
+            @brief Moves the Drone in the Right/Left-direction by the specifed amount.
+            @param value  The amount by which the drone is to be moved.
+            */
+            inline void moveRightLeft(float value)
+            { this->moveRightLeft(Vector2(value, 0)); }
+            /**
+            @brief Moves the Drone in the Up/Down-direction by the specifed amount.
+            @param value  The amount by which the drone is to be moved.
+            */
+            inline void moveUpDown(float value)
+            { this->moveUpDown(Vector2(value, 0)); }
+
+            /**
+            @brief Rotates the Drone around the y-axis by the specifed amount.
+            @param value  The amount by which the drone is to be rotated.
+            */
+            inline void rotateYaw(float value)
+            { this->rotateYaw(Vector2(value, 0)); }
+            /**
+            @brief Rotates the Drone around the x-axis by the specifed amount.
+            @param value  The amount by which the drone is to be rotated.
+            */
+            inline void rotatePitch(float value)
+            { this->rotatePitch(Vector2(value, 0)); }
+            /**
+            @brief Rotates the Drone around the z-axis by the specifed amount.
+            @param value  The amount by which the drone is to be rotated.
+            */
+            inline void rotateRoll(float value)
+            { this->rotateRoll(Vector2(value, 0)); }
+
+            /**
+            @brief Sets the primary thrust to the input amount.
+            @param thrust The amount of thrust.
+            */
+            inline void setPrimaryThrust( float thrust )
+                { this->primaryThrust_=thrust; }
+            inline void setAuxilaryThrust( float thrust )
+                { this->auxilaryThrust_=thrust; }
+            inline void setRotationThrust( float thrust )
+                { this->rotationThrust_=thrust; }
+            inline void setMaxDistanceToOwner( float distance)
+                { this->maxDistanceToOwner_=distance; }
+            inline void setMinDistanceToOwner( float distance)
+                { this->minDistanceToOwner_=distance; }
+            inline void setMaxShootingRange( float distance)
+                { this->maxShootingRange_=distance; }
+
+
+            /**
+            @brief Gets the primary thrust to the input amount.
+            @return The amount of thrust.
+            */
+            inline float getPrimaryThrust()
+                { return this->primaryThrust_; }
+            inline float getAuxilaryThrust()
+                { return this->auxilaryThrust_; }
+            inline float getRotationThrust()
+                { return this->rotationThrust_; }
+            inline float getMaxDistanceToOwner()
+                { return this->maxDistanceToOwner_; }
+            inline float getMinDistanceToOwner()
+                { return this->minDistanceToOwner_; }
+            inline float getMaxShootingRange()
+                { return this->maxShootingRange_; }
+
+        private:
+            DroneController *myController_; //!< The controller of the Drone.
+
+            btVector3 localLinearAcceleration_; //!< The linear acceleration that is used to move the Drone the next tick.
+            btVector3 localAngularAcceleration_; //!< The linear angular acceleration that is used to move the Drone the next tick.
+            float primaryThrust_; //!< The amount of primary thrust. This is just used, when moving forward.
+            float auxilaryThrust_; //!< The amount of auxilary thrust. Used for all other movements (except for rotations).
+            float rotationThrust_; //!< The amount of rotation thrust. Used for rotations only.
+            float maxDistanceToOwner_; //Maximum Distance to owner
+            float minDistanceToOwner_; //Minimum Distance to owner
+            float maxShootingRange_;
+    };
+
+}
+
+#endif /* _Drone_H__ */
Index: code/trunk/src/orxonox/worldentities/ExplosionChunk.h
===================================================================
--- code/trunk/src/orxonox/worldentities/ExplosionChunk.h	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/ExplosionChunk.h	(revision 7163)
@@ -44,5 +44,4 @@
 
             virtual void tick(float dt);
-            void registerVariables();
 
             inline void setLOD(LODParticle::Value level)
@@ -52,4 +51,5 @@
 
         private:
+            void registerVariables();
             void LODchanged();
             void checkStop();
Index: code/trunk/src/orxonox/worldentities/MobileEntity.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/MobileEntity.cc	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/MobileEntity.cc	(revision 7163)
@@ -46,6 +46,4 @@
         this->angularAcceleration_ = Vector3::ZERO;
         this->angularVelocity_     = Vector3::ZERO;
-
-        this->registerVariables();
     }
 
Index: code/trunk/src/orxonox/worldentities/MovableEntity.h
===================================================================
--- code/trunk/src/orxonox/worldentities/MovableEntity.h	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/MovableEntity.h	(revision 7163)
@@ -48,5 +48,4 @@
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
             virtual bool collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint);
-            void registerVariables();
 
             using WorldEntity::setPosition;
@@ -79,4 +78,5 @@
 
         private:
+            void registerVariables();
             void clientConnected(unsigned int clientID);
             void clientDisconnected(unsigned int clientID);
Index: code/trunk/src/orxonox/worldentities/StaticEntity.h
===================================================================
--- code/trunk/src/orxonox/worldentities/StaticEntity.h	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/StaticEntity.h	(revision 7163)
@@ -42,6 +42,4 @@
             virtual ~StaticEntity();
 
-            void registerVariables();
-
             using WorldEntity::setPosition;
             using WorldEntity::setOrientation;
@@ -51,4 +49,5 @@
 
         private:
+            void registerVariables();
             bool isCollisionTypeLegal(CollisionType type) const;
 
Index: code/trunk/src/orxonox/worldentities/WorldEntity.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/WorldEntity.cc	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/WorldEntity.cc	(revision 7163)
@@ -81,5 +81,5 @@
         this->node_->setPosition(Vector3::ZERO);
         this->node_->setOrientation(Quaternion::IDENTITY);
-        
+
         // Activity and visibility memory.
         this->bActiveMem_ = true;
@@ -205,5 +205,5 @@
         registerVariable(this->parentID_,       VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::networkcallback_parentChanged));
     }
-    
+
     /**
     @brief
@@ -213,5 +213,5 @@
     {
         SUPER(WorldEntity, changedActivity);
-        
+
         for (std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin(); it != this->getAttachedObjects().end(); it++)
         {
@@ -227,5 +227,5 @@
         }
     }
-    
+
     /**
     @brief
@@ -235,5 +235,5 @@
     {
         SUPER(WorldEntity, changedVisibility);
-        
+
         for (std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin(); it != this->getAttachedObjects().end(); it++)
         {
Index: code/trunk/src/orxonox/worldentities/WorldEntity.h
===================================================================
--- code/trunk/src/orxonox/worldentities/WorldEntity.h	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/WorldEntity.h	(revision 7163)
@@ -94,5 +94,4 @@
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-            void registerVariables();
 
             inline const Ogre::SceneNode* getNode() const
@@ -105,5 +104,5 @@
             static const Vector3 DOWN;
             static const Vector3 UP;
-            
+
             virtual void changedActivity(void);
             virtual void changedVisibility(void);
@@ -214,4 +213,6 @@
 
         private:
+            void registerVariables();
+            
             inline void lookAt_xmlport(const Vector3& target)
                 { this->lookAt(target); }
@@ -234,5 +235,5 @@
             std::set<WorldEntity*> children_;
             bool bDeleteWithParent_;
-            
+
             bool bActiveMem_;
             bool bVisibleMem_;
Index: code/trunk/src/orxonox/worldentities/pawns/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/CMakeLists.txt	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/pawns/CMakeLists.txt	(revision 7163)
@@ -1,3 +1,4 @@
 ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  FpsPlayer.cc
   Spectator.cc
   Pawn.cc
Index: code/trunk/src/orxonox/worldentities/pawns/FpsPlayer.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/FpsPlayer.cc	(revision 7163)
+++ code/trunk/src/orxonox/worldentities/pawns/FpsPlayer.cc	(revision 7163)
@@ -0,0 +1,307 @@
+/*
+ *   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:
+ *      Cyrill Frei
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FpsPlayer.h"
+
+#include <OgreSceneNode.h>
+#include <BulletDynamics/Dynamics/btRigidBody.h>
+#include <LinearMath/btVector3.h>
+#include <BulletCollision/NarrowPhaseCollision/btManifoldPoint.h>
+#include <OgreSceneManager.h>
+#include <OgreSceneNode.h>
+#include <OgreEntity.h>
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/Template.h"
+#include "core/XMLPort.h"
+#include "items/Engine.h"
+#include "Scene.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/WeaponSlot.h"
+#include "weaponsystem/Weapon.h"
+
+#include <cmath>
+
+namespace orxonox
+{
+    const float orientationGain_ = 100;
+    const float jumpValue_ = 300;
+    CreateFactory(FpsPlayer);
+
+    FpsPlayer::FpsPlayer(BaseObject* creator) : Pawn(creator)
+    {
+        RegisterObject(FpsPlayer);
+        this->speed_ = 200;
+        this->localVelocity_ = Vector3::ZERO;
+/*
+ *        this->primaryThrust_  = 100;
+ *        this->auxilaryThrust_ =  30;
+ *        this->rotationThrust_ =  10;
+ *
+ *        this->localLinearAcceleration_.setValue(0, 0, 0);
+ *        this->localAngularAcceleration_.setValue(0, 0, 0);
+ *        this->bBoost_ = false;
+ *        this->bPermanentBoost_ = false;
+ *        this->steering_ = Vector3::ZERO;
+*/
+
+
+        this->bInvertYAxis_ = false;
+
+        this->setDestroyWhenPlayerLeft(true);
+
+        // FpsPlayer is always a physical object per default
+        // Be aware of this call: The collision type legality check will not reach derived classes!
+        this->setCollisionType(WorldEntity::Dynamic);
+        // Get notification about collisions
+        this->enableCollisionCallback();
+
+        this->setConfigValues();
+        this->registerVariables();
+
+        //this->weaponNode = this->cameraPositionRootNode_;
+        this->weaponNode_ = this->getScene()->getRootSceneNode()->createChildSceneNode();
+        this->attachNode(this->weaponNode_);
+    }
+
+    FpsPlayer::~FpsPlayer()
+    {
+        if (this->isInitialized())
+        {
+            if (this->mesh_.getEntity())
+                this->detachOgreObject(this->mesh_.getEntity());
+
+            if (this->weaponNode_ && this->getScene()->getSceneManager())
+                this->getScene()->getSceneManager()->destroySceneNode(this->weaponNode_->getName());
+        }
+    }
+
+    void FpsPlayer::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(FpsPlayer, XMLPort, xmlelement, mode);
+
+        XMLPortParamVariable(FpsPlayer, "primaryThrust",  primaryThrust_,  xmlelement, mode);
+        XMLPortParamVariable(FpsPlayer, "auxilaryThrust", auxilaryThrust_, xmlelement, mode);
+        XMLPortParamVariable(FpsPlayer, "rotationThrust", rotationThrust_, xmlelement, mode);
+        XMLPortParam(FpsPlayer, "weapon", setMeshSource, getMeshSource, xmlelement, mode);
+    }
+
+    void FpsPlayer::registerVariables()
+    {
+        registerVariable(this->primaryThrust_,  VariableDirection::ToClient);
+        registerVariable(this->auxilaryThrust_, VariableDirection::ToClient);
+        registerVariable(this->rotationThrust_, VariableDirection::ToClient);
+        registerVariable(this->weaponMashName_, VariableDirection::ToClient);
+    }
+
+
+
+    void FpsPlayer::setConfigValues()
+    {
+        SetConfigValue(bInvertYAxis_, false).description("Set this to true for joystick-like mouse behaviour (mouse up = targetting down).");
+    }
+
+    bool FpsPlayer::isCollisionTypeLegal(WorldEntity::CollisionType type) const
+    {
+        if (type != WorldEntity::Dynamic)
+        {
+            CCOUT(1) << "Error: Cannot tell a FpsPlayer not to be dynamic! Ignoring." << std::endl;
+            assert(false); // Only in debug mode
+            return false;
+        }
+        else
+            return true;
+    }
+
+    void FpsPlayer::tick(float dt)
+    {
+        if (this->hasLocalController())
+        {
+            this->setOrientation(savedOrientation_);
+
+            this->thisTickBoost_ = false;
+
+            float localSpeedSquared = this->localVelocity_.squaredLength();
+            float localSpeed;
+            if (localSpeedSquared > 1.0)
+                localSpeed = this->speed_ / sqrtf(localSpeedSquared);
+            else
+                localSpeed = this->speed_;
+
+            this->localVelocity_.x *= localSpeed;
+            this->localVelocity_.z *= localSpeed;
+            Vector3 temp = this->getOrientation() * this->localVelocity_;
+            if (localVelocity_.y == jumpValue_)
+                this->setVelocity(Vector3(temp.x, temp.y + this->getVelocity().y, temp.z));
+            else
+                this->setVelocity(Vector3(temp.x, this->getVelocity().y, temp.z));
+            this->localVelocity_.x = 0;
+            this->localVelocity_.y = 0;
+            this->localVelocity_.z = 0;
+
+            if (!this->isInMouseLook())
+            {
+                this->yaw(Radian(this->yaw_ * this->getMouseLookSpeed()), WorldEntity::Parent);
+
+                Radian pitch = this->cameraPositionRootNode_->getOrientation().getPitch();
+                if (pitch < Radian(1.5707) && pitch > Radian(-1.5707))
+                {
+                    this->cameraPositionRootNode_->pitch(Radian(this->pitch_ * this->getMouseLookSpeed()));
+                }
+                else if (pitch < Radian(-1.5707))
+                {
+                    if (this->pitch_ > 0.0)
+                        this->cameraPositionRootNode_->pitch(Radian(this->pitch_ * this->getMouseLookSpeed()));
+                    else if (pitch < Radian(-1.571))
+                        this->cameraPositionRootNode_->pitch(-pitch + Radian(-1.570796));
+                }
+                else if (pitch > Radian(1.5707))
+                {
+                    if (this->pitch_ < 0.0)
+                        this->cameraPositionRootNode_->pitch(Radian(this->pitch_ * this->getMouseLookSpeed()));
+                    else if (pitch > Radian(1.571))
+                        this->cameraPositionRootNode_->pitch(-pitch + Radian(1.570796));
+                }
+                this->weaponNode_->setOrientation(this->cameraPositionRootNode_->getOrientation());
+            }
+
+            this->yaw_ = this->pitch_ = this->roll_ = 0;
+
+            this->setAngularVelocity(0.0, 0.0, 0.0);
+            this->savedOrientation_ = this->getOrientation();
+        }
+
+        SUPER(FpsPlayer, tick, dt);
+    }
+
+    void FpsPlayer::changedMesh()
+    {
+        if (GameMode::showsGraphics())
+        {
+            if (this->mesh_.getEntity())
+                this->weaponNode_->detachObject(this->mesh_.getEntity());
+
+            this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
+
+            if (this->mesh_.getEntity())
+            {
+                this->weaponNode_->attachObject(this->mesh_.getEntity());
+            }
+        }
+    }
+
+    void FpsPlayer::setPlayer(PlayerInfo* player)
+    {
+        ControllableEntity::setPlayer(player);
+
+//        this->setSyncMode(ObjectDirection::ToClient);
+    }
+
+    void FpsPlayer::startLocalHumanControl()
+    {
+        ControllableEntity::startLocalHumanControl();
+    }
+
+    void FpsPlayer::moveFrontBack(const Vector2& value)
+    {
+        this->localVelocity_.z -= value.x;
+    }
+
+
+    void FpsPlayer::moveRightLeft(const Vector2& value)
+    {
+        this->localVelocity_.x += value.x;
+    }
+
+    void FpsPlayer::moveUpDown(const Vector2& value)
+    {
+        //this->localVelocity_.y += value.x;
+    }
+
+    void FpsPlayer::rotateYaw(const Vector2& value)
+    {
+        this->yaw_ += value.y;
+
+        ControllableEntity::rotateYaw(value);
+    }
+
+    void FpsPlayer::rotatePitch(const Vector2& value)
+    {
+        this->pitch_ += value.y;
+
+        ControllableEntity::rotatePitch(value);
+    }
+
+    void FpsPlayer::rotateRoll(const Vector2& value)
+    {
+        this->roll_ += value.y;
+
+        ControllableEntity::rotateRoll(value);
+    }
+
+    void FpsPlayer::fire()
+    {
+    }
+
+    void FpsPlayer::boost() //acctually jump
+    {
+        if (this->isFloor_)
+        {
+            if (!this->thisTickBoost_)
+                this->localVelocity_.y = jumpValue_;
+            //this->physicalBody_->applyCentralImpulse(btVector3(0, jumpvalue, 0));
+            this->thisTickBoost_ = true;
+            this->isFloor_ = false;
+        }
+    }
+
+    bool FpsPlayer::collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint)
+    {
+        if (contactPoint.m_normalWorldOnB.y() > 0.6)
+            this->isFloor_ = true;
+        else
+            this->isFloor_ = false;
+
+        return false;
+    }
+
+    void FpsPlayer::addedWeaponPack(WeaponPack* wPack)
+    {
+        for (size_t i = 0; i < wPack->getNumWeapons(); ++i)
+        {
+            Weapon* weapon = wPack->getWeapon(i);
+            if (weapon->getWeaponSlot())
+            {
+                weapon->getWeaponSlot()->removeWeapon();
+                weapon->detachFromParent();
+                weapon->attachToNode(this->weaponNode_);
+            }
+        }
+    }
+}
Index: code/trunk/src/orxonox/worldentities/pawns/FpsPlayer.h
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/FpsPlayer.h	(revision 7163)
+++ code/trunk/src/orxonox/worldentities/pawns/FpsPlayer.h	(revision 7163)
@@ -0,0 +1,108 @@
+/*
+ *   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:
+ *      Cyrill Frei
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FpsPlayer_H__
+#define _FpsPlayer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include <LinearMath/btVector3.h>
+#include "util/Math.h"
+#include "tools/Mesh.h"
+#include "Pawn.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport FpsPlayer : public Pawn
+    {
+        public:
+            FpsPlayer(BaseObject* creator);
+            virtual ~FpsPlayer();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+            void registerVariables();
+            void setConfigValues();
+
+            virtual void moveFrontBack(const Vector2& value);
+            virtual void moveRightLeft(const Vector2& value);
+            virtual void moveUpDown(const Vector2& value);
+
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
+
+
+            inline void setMeshSource(const std::string& meshname)
+                { this->meshSrc_ = meshname; this->changedMesh(); }
+            inline const std::string& getMeshSource() const
+                { return this->meshSrc_; }
+
+            void boost(); //acctually jump
+
+            virtual void fire();
+
+            bool collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint);
+
+            virtual void addedWeaponPack(WeaponPack* wPack);
+
+        protected:
+            virtual void setPlayer(PlayerInfo* player);
+            virtual void startLocalHumanControl();
+            bool bInvertYAxis_;
+
+            bool bBoost_;
+            bool bPermanentBoost_;
+            Vector3 steering_;
+            float primaryThrust_;
+            float auxilaryThrust_;
+            float rotationThrust_;
+            std::string weaponMashName_;
+            btVector3 localLinearAcceleration_;
+            btVector3 localAngularAcceleration_;
+
+        private:
+            virtual bool isCollisionTypeLegal(WorldEntity::CollisionType type) const;
+            float speed_;
+
+            void changedMesh();
+            Mesh mesh_;
+            std::string meshSrc_;
+            float yaw_;
+            float pitch_;
+            float roll_;
+            Vector3 localVelocity_;
+            bool isFloor_;
+            bool thisTickBoost_;
+            Quaternion savedOrientation_;
+            Ogre::SceneNode* weaponNode_;
+    };
+}
+
+#endif /* _FpsPlayer_H__ */
Index: code/trunk/src/orxonox/worldentities/pawns/Pawn.cc
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/Pawn.cc	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/pawns/Pawn.cc	(revision 7163)
@@ -53,5 +53,7 @@
     CreateFactory(Pawn);
 
-    Pawn::Pawn(BaseObject* creator) : ControllableEntity(creator)
+    Pawn::Pawn(BaseObject* creator)
+        : ControllableEntity(creator)
+        , RadarViewable(creator, static_cast<WorldEntity*>(this))
     {
         RegisterObject(Pawn);
@@ -64,4 +66,6 @@
         this->maxHealth_ = 0;
         this->initialHealth_ = 0;
+        this->shieldHealth_ = 0;
+        this->shieldAbsorption_ = 0.5;
 
         this->lastHitOriginator_ = 0;
@@ -78,6 +82,4 @@
         else
             this->weaponSystem_ = 0;
-        
-        this->setCarrierName("Pawn");
 
         this->setRadarObjectColour(ColourValue::Red);
@@ -105,4 +107,8 @@
         XMLPortParam(Pawn, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
         XMLPortParam(Pawn, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
+
+        XMLPortParam(Pawn, "shieldhealth", setShieldHealth, getShieldHealth, xmlelement, mode).defaultValues(0);
+        XMLPortParam(Pawn, "shieldabsorption", setShieldAbsorption, getShieldAbsorption, xmlelement, mode).defaultValues(0);
+
         XMLPortParam(Pawn, "spawnparticlesource", setSpawnParticleSource, getSpawnParticleSource, xmlelement, mode);
         XMLPortParam(Pawn, "spawnparticleduration", setSpawnParticleDuration, getSpawnParticleDuration, xmlelement, mode).defaultValues(3.0f);
@@ -116,9 +122,11 @@
     void Pawn::registerVariables()
     {
-        registerVariable(this->bAlive_,        VariableDirection::ToClient);
-        registerVariable(this->health_,        VariableDirection::ToClient);
-        registerVariable(this->initialHealth_, VariableDirection::ToClient);
-        registerVariable(this->bReload_,       VariableDirection::ToServer);
-        registerVariable(this->aimPosition_,   Bidirectionality::ServerMaster, 0, true);
+        registerVariable(this->bAlive_,           VariableDirection::ToClient);
+        registerVariable(this->health_,           VariableDirection::ToClient);
+        registerVariable(this->initialHealth_,    VariableDirection::ToClient);
+        registerVariable(this->shieldHealth_,     VariableDirection::ToClient);
+        registerVariable(this->shieldAbsorption_, VariableDirection::ToClient);
+        registerVariable(this->bReload_,          VariableDirection::ToServer);
+        registerVariable(this->aimPosition_,      VariableDirection::ToServer);  // For the moment this variable gets only transfered to the server
     }
 
@@ -162,5 +170,22 @@
         if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
         {
-            this->setHealth(this->health_ - damage);
+            //share the dealt damage to the shield and the Pawn.
+            float shielddamage = damage*this->shieldAbsorption_;
+            float healthdamage = damage*(1-this->shieldAbsorption_);
+
+            // In case the shield can not take all the shield damage.
+            if (shielddamage > this->getShieldHealth())
+            {
+                healthdamage += shielddamage-this->getShieldHealth();
+                this->setShieldHealth(0);
+            }
+
+            this->setHealth(this->health_ - healthdamage);
+
+            if (this->getShieldHealth() > 0)
+            {
+                this->setShieldHealth(this->shieldHealth_ - shielddamage);
+            }
+
             this->lastHitOriginator_ = originator;
 
@@ -336,5 +361,8 @@
     {
         if (this->weaponSystem_)
+        {
             this->weaponSystem_->addWeaponPack(wPack);
+            this->addedWeaponPack(wPack);
+        }
     }
 
@@ -342,6 +370,10 @@
     {
         if (this->weaponSystem_)
+        {
             if (!this->weaponSystem_->addWeaponPack(wPack))
                 wPack->destroy();
+            else
+                this->addedWeaponPack(wPack);
+        }
     }
 
Index: code/trunk/src/orxonox/worldentities/pawns/Pawn.h
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/Pawn.h	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/pawns/Pawn.h	(revision 7163)
@@ -50,5 +50,4 @@
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
             virtual void tick(float dt);
-            void registerVariables();
 
             inline bool isAlive() const
@@ -73,4 +72,14 @@
                 { return this->initialHealth_; }
 
+            inline void setShieldHealth(float shieldHealth)
+            { this->shieldHealth_ = shieldHealth; }
+            inline float getShieldHealth()
+            { return this->shieldHealth_; }
+
+            inline void setShieldAbsorption(float shieldAbsorption)
+            { this->shieldAbsorption_ = shieldAbsorption; }
+            inline float getShieldAbsorption()
+            { return this->shieldAbsorption_; }
+
             inline ControllableEntity* getLastHitOriginator() const
                 { return this->lastHitOriginator_; }
@@ -91,4 +100,6 @@
             void addWeaponPackXML(WeaponPack * wPack);
             WeaponPack * getWeaponPack(unsigned int index) const;
+
+            virtual void addedWeaponPack(WeaponPack* wPack) {}
 
             inline const WorldEntity* getWorldEntity() const
@@ -116,5 +127,5 @@
             Vector3 getAimPosition()
                 { return this->aimPosition_; }
-                
+
             virtual const Vector3& getCarrierPosition(void)
                 { return this->getWorldPosition(); };
@@ -141,4 +152,6 @@
             float maxHealth_;
             float initialHealth_;
+            float shieldHealth_;
+            float shieldAbsorption_; // Has to be between 0 and 1
 
             Pawn* lastHitOriginator_;
@@ -152,4 +165,5 @@
 
         private:
+            void registerVariables();
             inline void setWeaponSystem(WeaponSystem* weaponsystem)
                 { this->weaponSystem_ = weaponsystem; }
Index: code/trunk/src/orxonox/worldentities/pawns/SpaceShip.h
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/SpaceShip.h	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/pawns/SpaceShip.h	(revision 7163)
@@ -47,5 +47,4 @@
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
             virtual void tick(float dt);
-            void registerVariables();
             void setConfigValues();
 
@@ -99,7 +98,7 @@
 
         private:
+            void registerVariables();
             virtual bool isCollisionTypeLegal(WorldEntity::CollisionType type) const;
 
-        private:
             void loadEngineTemplate();
 
Index: code/trunk/src/orxonox/worldentities/pawns/Spectator.h
===================================================================
--- code/trunk/src/orxonox/worldentities/pawns/Spectator.h	(revision 6901)
+++ code/trunk/src/orxonox/worldentities/pawns/Spectator.h	(revision 7163)
@@ -44,5 +44,4 @@
 
             void setConfigValues();
-            void registerVariables();
             virtual void tick(float dt);
 
@@ -63,4 +62,5 @@
 
         private:
+            void registerVariables();
             void changedGreeting();
             void changedFlareVisibility();
