Index: code/branches/netp3/src/network/CMakeLists.txt
===================================================================
--- code/branches/netp3/src/network/CMakeLists.txt	(revision 2989)
+++ code/branches/netp3/src/network/CMakeLists.txt	(revision 2990)
@@ -25,11 +25,13 @@
   ClientConnectionListener.cc
   ConnectionManager.cc
+  FunctionCallManager.cc
   GamestateManager.cc
   GamestateClient.cc
   GamestateHandler.cc
+  NetworkFunction.cc
+  Host.cc
   PacketBuffer.cc
   Server.cc
   TrafficControl.cc
-  Host.cc
 )
 ADD_SUBDIRECTORY(packet)
Index: code/branches/netp3/src/network/Client.cc
===================================================================
--- code/branches/netp3/src/network/Client.cc	(revision 2989)
+++ code/branches/netp3/src/network/Client.cc	(revision 2990)
@@ -48,4 +48,5 @@
 #include "core/CoreIncludes.h"
 #include "packet/Packet.h"
+#include "FunctionCallManager.h"
 
 // #include "packet/Acknowledgement.h"
@@ -140,31 +141,38 @@
    */
   void Client::update(const Clock& time){
-//     COUT(3) << ".";
-    if(client_connection.isConnected() && isSynched_){
-      COUT(4) << "popping partial gamestate: " << std::endl;
-      packet::Gamestate *gs = gamestate.getGamestate();
-      if(gs){
-        COUT(4) << "client tick: sending gs " << gs << std::endl;
-        if( !gs->send() )
-          COUT(3) << "Problem adding partial gamestate to queue" << std::endl;
+    //this steers our network frequency
+    timeSinceLastUpdate_+=time;
+    if(timeSinceLastUpdate_>=NETWORK_PERIOD){
+      timeSinceLastUpdate_ -= static_cast<unsigned int>( timeSinceLastUpdate_ / NETWORK_PERIOD ) * NETWORK_PERIOD;
+      //     COUT(3) << ".";
+      if(client_connection.isConnected() && isSynched_){
+        COUT(4) << "popping partial gamestate: " << std::endl;
+        packet::Gamestate *gs = gamestate.getGamestate();
+        if(gs){
+          COUT(4) << "client tick: sending gs " << gs << std::endl;
+          if( !gs->send() )
+            COUT(3) << "Problem adding partial gamestate to queue" << std::endl;
         // gs gets automatically deleted by enet callback
+        }
+        FunctionCallManager::sendCalls();
       }
+      ENetEvent *event;
+    // stop if the packet queue is empty
+      while(!(client_connection.queueEmpty())){
+        event = client_connection.getEvent();
+        COUT(5) << "tick packet size " << event->packet->dataLength << std::endl;
+        packet::Packet *packet = packet::Packet::createPacket(event->packet, event->peer);
+      // note: packet commits suicide here except for the GameState. That is then deleted by a GamestateHandler
+        bool b = packet->process();
+        assert(b);
+      }
+      if(gamestate.processGamestates())
+      {
+        if(!isSynched_)
+          isSynched_=true;
+      }
+      gamestate.cleanup();
     }
-    ENetEvent *event;
-    // stop if the packet queue is empty
-    while(!(client_connection.queueEmpty())){
-      event = client_connection.getEvent();
-      COUT(5) << "tick packet size " << event->packet->dataLength << std::endl;
-      packet::Packet *packet = packet::Packet::createPacket(event->packet, event->peer);
-      // note: packet commits suicide here except for the GameState. That is then deleted by a GamestateHandler
-      bool b = packet->process();
-      assert(b);
-    }
-    if(gamestate.processGamestates())
-    {
-      if(!isSynched_)
-        isSynched_=true;
-    }
-    gamestate.cleanup();
+
     return;
   }
Index: code/branches/netp3/src/network/Client.h
===================================================================
--- code/branches/netp3/src/network/Client.h	(revision 2989)
+++ code/branches/netp3/src/network/Client.h	(revision 2990)
@@ -88,4 +88,5 @@
 
     bool gameStateFailure_;
+    float timeSinceLastUpdate_;
   };
 
Index: code/branches/netp3/src/network/ClientConnection.cc
===================================================================
--- code/branches/netp3/src/network/ClientConnection.cc	(revision 2989)
+++ code/branches/netp3/src/network/ClientConnection.cc	(revision 2990)
@@ -42,4 +42,5 @@
 #include <enet/enet.h>
 #include <iostream>
+#include <cassert>
 // boost.thread library for multithreading support
 #include <boost/thread/thread.hpp>
@@ -57,5 +58,5 @@
 
   ClientConnection::ClientConnection(int port, const std::string& address) {
-    quit=false;
+    quit_=false;
     server=NULL;
     serverAddress = new ENetAddress();
@@ -66,5 +67,5 @@
 
   ClientConnection::ClientConnection(int port, const char *address) {
-    quit=false;
+    quit_=false;
     server=NULL;
     serverAddress = new ENetAddress();
@@ -106,5 +107,5 @@
 
   bool ClientConnection::closeConnection() {
-    quit=true;
+    quit_=true;
     //network_threads.join_all();
     receiverThread_->join();
@@ -150,15 +151,15 @@
       COUT(2) << "ClientConnection: could not create client host" << std::endl;
       // add some error handling here ==========================
-      quit=true;
+      quit_=true;
     }
     //connect to the server
     if(!establishConnection()){
       COUT(2) << "clientConn: receiver thread: could not establishConnection" << std::endl;
-      quit=true;
+      quit_=true;
       return;
     }
     event = new ENetEvent;
     //main loop
-    while(!quit){
+    while(!quit_){
       //std::cout << "connection loop" << std::endl;
       {
@@ -166,6 +167,8 @@
         if(enet_host_service(client, event, NETWORK_CLIENT_WAIT_TIME)<0){
           // we should never reach this point
-          quit=true;
-          continue;
+// 	        assert(0);
+          printf("ClientConnection: ENet returned with an error!\n");
+          quit_=true;
+          break;
           // add some error handling here ========================
         }
@@ -183,5 +186,6 @@
         break;
       case ENET_EVENT_TYPE_DISCONNECT:
-        quit=true;
+        quit_=true;
+        printf("Received disconnect Packet from Server!\n");
         // server closed the connection
         return;
@@ -206,5 +210,5 @@
     boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
     enet_peer_disconnect(server, 0);
-    while(enet_host_service(client, &event, NETWORK_CLIENT_WAIT_TIME) > 0){
+    while(enet_host_service(client, &event, NETWORK_CLIENT_WAIT_TIME) >= 0){
       switch (event.type)
       {
@@ -233,5 +237,5 @@
     }
     // handshake
-    while(enet_host_service(client, &event, NETWORK_CLIENT_WAIT_TIME)>=0 && !quit){
+    while(enet_host_service(client, &event, NETWORK_CLIENT_WAIT_TIME)>=0 && !quit_){
       if( event.type == ENET_EVENT_TYPE_CONNECT ){
         established=true;
Index: code/branches/netp3/src/network/ClientConnection.h
===================================================================
--- code/branches/netp3/src/network/ClientConnection.h	(revision 2989)
+++ code/branches/netp3/src/network/ClientConnection.h	(revision 2990)
@@ -53,5 +53,5 @@
     const int NETWORK_PORT = 55556;
     const int NETWORK_CLIENT_MAX_CONNECTIONS = 5;
-    const int NETWORK_CLIENT_WAIT_TIME = 1;
+    const int NETWORK_CLIENT_WAIT_TIME = 10;
     const int NETWORK_CLIENT_CONNECT_TIMEOUT = 3000; // miliseconds
     const int NETWORK_CLIENT_CHANNELS = 2;
@@ -76,5 +76,6 @@
     //bool sendPackets(ENetEvent *event);
     bool waitEstablished(int milisec);
-    bool isConnected(){return established;}
+    inline bool isConnected(){return established;}
+    inline bool checkConnection(){ return !quit_ && isConnected(); }
   private:
     ClientConnection(const ClientConnection& copy); // not used
@@ -90,5 +91,5 @@
     ENetAddress *serverAddress;
     // quit-variable (communication with threads)
-    bool quit;
+    bool quit_;
     bool established;
     // clientlist
Index: code/branches/netp3/src/network/ConnectionManager.cc
===================================================================
--- code/branches/netp3/src/network/ConnectionManager.cc	(revision 2989)
+++ code/branches/netp3/src/network/ConnectionManager.cc	(revision 2990)
@@ -58,8 +58,5 @@
 {
   bool operator< (ENetAddress a, ENetAddress b) {
-    if(a.host <= b.host)
-      return true;
-    else
-      return false;
+    return a.host <= b.host;
   }
 }
@@ -75,5 +72,5 @@
     assert(instance_==0);
     instance_=this;
-    quit=false;
+    quit_=false;
     bindAddress = new ENetAddress();
     bindAddress->host = ENET_HOST_ANY;
@@ -84,5 +81,5 @@
     assert(instance_==0);
     instance_=this;
-    quit=false;
+    quit_=false;
     bindAddress = new ENetAddress();
     bindAddress->host = ENET_HOST_ANY;
@@ -93,5 +90,5 @@
     assert(instance_==0);
     instance_=this;
-    quit=false;
+    quit_=false;
     bindAddress = new ENetAddress();
     enet_address_set_host (bindAddress, address.c_str());
@@ -102,5 +99,5 @@
     assert(instance_==0);
     instance_=this;
-    quit=false;
+    quit_=false;
     bindAddress = new ENetAddress();
     enet_address_set_host (bindAddress, address);
@@ -109,5 +106,5 @@
 
   ConnectionManager::~ConnectionManager(){
-    if(!quit)
+    if(!quit_)
       quitListener();
     instance_=0;
@@ -133,5 +130,5 @@
 
   bool ConnectionManager::quitListener() {
-    quit=true;
+    quit_=true;
     receiverThread_->join();
     return true;
@@ -189,16 +186,19 @@
     if(server==NULL){
       // add some error handling here ==========================
-      quit=true;
+      quit_=true;
       return;
     }
 
     event = new ENetEvent;
-    while(!quit){
+    while(!quit_)
+    {
       { //mutex scope
         boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
         if(enet_host_service(server, event, NETWORK_WAIT_TIMEOUT)<0){
           // we should never reach this point
-          quit=true;
+          printf("ConnectionManager: ENet returned with an error\n");
+          quit_=true;
           continue;
+          printf("waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhh");
           // add some error handling here ========================
         }
@@ -208,4 +208,5 @@
         // log handling ================
         case ENET_EVENT_TYPE_CONNECT:
+          printf("====================================================================");
         case ENET_EVENT_TYPE_DISCONNECT:
         case ENET_EVENT_TYPE_RECEIVE:
@@ -215,5 +216,5 @@
         case ENET_EVENT_TYPE_NONE:
           //receiverThread_->yield();
-          msleep(1);
+          msleep(10);
           break;
       }
@@ -267,11 +268,4 @@
   }
 
-  bool ConnectionManager::processData(ENetEvent *event) {
-    // just add packet to the buffer
-    // this can be extended with some preprocessing
-    return buffer.push(event);
-  }
-
-
 
   int ConnectionManager::getClientID(ENetPeer* peer) {
Index: code/branches/netp3/src/network/ConnectionManager.h
===================================================================
--- code/branches/netp3/src/network/ConnectionManager.h	(revision 2989)
+++ code/branches/netp3/src/network/ConnectionManager.h	(revision 2990)
@@ -55,5 +55,5 @@
     const int NETWORK_PORT = 55556;
     const int NETWORK_MAX_CONNECTIONS = 50;
-    const int NETWORK_WAIT_TIMEOUT = 1;
+    const int NETWORK_WAIT_TIMEOUT = 10;
     const int NETWORK_DEFAULT_CHANNEL = 0;
 
@@ -81,8 +81,9 @@
     void disconnectClient(ClientInformation *client);
     void syncClassid(unsigned int clientID);
+    bool checkReceiverThread(){ return !quit_; }
 
   private:
     ConnectionManager(const ConnectionManager& copy); // not used
-    bool processData(ENetEvent *event);
+    inline bool processData(ENetEvent *event){ return buffer.push(event); }
     void receiverThread();
     void disconnectClients();
@@ -95,5 +96,5 @@
     ENetAddress *bindAddress;
 
-    bool quit; // quit-variable (communication with threads)
+    bool quit_; // quit-variable (communication with threads)
 
     boost::thread *receiverThread_;
Index: code/branches/netp3/src/network/FunctionCallManager.cc
===================================================================
--- code/branches/netp3/src/network/FunctionCallManager.cc	(revision 2990)
+++ code/branches/netp3/src/network/FunctionCallManager.cc	(revision 2990)
@@ -0,0 +1,165 @@
+/*
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FunctionCallManager.h"
+#include "packet/FunctionCalls.h"
+
+namespace orxonox {
+    
+std::map<uint32_t, packet::FunctionCalls*> FunctionCallManager::clientMap_;
+
+// Static calls
+
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::	clientMap_[clientID]->addCallStatic(functionID);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3, &mt4);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3, &mt4, &mt5);
+}
+
+
+// MemberCalls
+
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3, &mt4);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3, &mt4, &mt5);
+}
+
+// Send calls
+
+void FunctionCallManager::sendCalls()
+{
+  std::map<uint32_t, packet::FunctionCalls*>::iterator it;
+  for (it = FunctionCallManager::clientMap_.begin(); it != FunctionCallManager::clientMap_.end(); it++ )
+  {
+    assert(!FunctionCallManager::clientMap_.empty());
+    it->second->send();
+  }
+  FunctionCallManager::clientMap_.clear();
+}
+
+
+} //namespace orxonox
Index: code/branches/netp3/src/network/FunctionCallManager.h
===================================================================
--- code/branches/netp3/src/network/FunctionCallManager.h	(revision 2990)
+++ code/branches/netp3/src/network/FunctionCallManager.h	(revision 2990)
@@ -0,0 +1,44 @@
+
+#ifndef NETWORKFUNCTIONCALLMANAGER_H
+#define NETWORKFUNCTIONCALLMANAGER_H
+
+#include "NetworkPrereqs.h"
+#include "packet/FunctionCalls.h"
+#include <map>
+
+
+namespace orxonox {
+/**
+	@author
+*/
+
+class MultiType;
+
+class _NetworkExport FunctionCallManager
+{
+public:
+  static void addCallStatic(uint32_t functionID, uint32_t clientID);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5);
+  
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5);
+  
+  static void sendCalls();
+  
+  static std::map<uint32_t, packet::FunctionCalls*> clientMap_;
+protected:
+  FunctionCallManager();
+  ~FunctionCallManager();
+};
+
+} //namespace orxonox
+
+#endif
Index: code/branches/netp3/src/network/Host.h
===================================================================
--- code/branches/netp3/src/network/Host.h	(revision 2989)
+++ code/branches/netp3/src/network/Host.h	(revision 2990)
@@ -35,4 +35,8 @@
 
 namespace orxonox {
+
+  const int CLIENTID_SERVER = 0;
+  const unsigned int NETWORK_FREQUENCY = 25;
+  const float NETWORK_PERIOD = 1.0f/NETWORK_FREQUENCY;
 
 /**
Index: code/branches/netp3/src/network/NetworkFunction.cc
===================================================================
--- code/branches/netp3/src/network/NetworkFunction.cc	(revision 2990)
+++ code/branches/netp3/src/network/NetworkFunction.cc	(revision 2990)
@@ -0,0 +1,91 @@
+/*
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "NetworkFunction.h"
+#include <string>
+#include "synchronisable/Synchronisable.h"
+
+namespace orxonox
+{
+  std::map<std::string, NetworkFunctionBase*> NetworkFunctionBase::nameMap_;
+  std::map<uint32_t, bool> NetworkFunctionBase::isStaticMap_;
+  
+  std::map<NetworkFunctionPointer, NetworkFunctionStatic*> NetworkFunctionStatic::functorMap_;
+  std::map<uint32_t, NetworkFunctionStatic*> NetworkFunctionStatic::idMap_;
+      
+  std::map<NetworkFunctionPointer, NetworkMemberFunctionBase*> NetworkMemberFunctionBase::functorMap_;
+  std::map<uint32_t, NetworkMemberFunctionBase*> NetworkMemberFunctionBase::idMap_;
+
+  NetworkFunctionBase::NetworkFunctionBase(std::string name)
+  {
+    RegisterRootObject(NetworkFunctionBase);
+    
+    static uint32_t networkID = 0;
+    this->networkID_ = networkID++;
+    
+    this->name_ = name;
+    nameMap_[name] = this;
+  }
+  NetworkFunctionBase::~NetworkFunctionBase()
+  {
+  }
+  
+  
+  
+  NetworkFunctionStatic::NetworkFunctionStatic(FunctorStatic* functor, std::string name, const NetworkFunctionPointer& p):
+    NetworkFunctionBase(name)
+  {
+    RegisterObject(NetworkFunctionStatic);
+    
+    this->functor_ = functor;
+    functorMap_[p] = this;
+    idMap_[ this->getNetworkID() ] = this;
+  }
+  
+  NetworkFunctionStatic::~NetworkFunctionStatic()
+  {
+    delete this->functor_;
+  }
+  
+  
+  
+  NetworkMemberFunctionBase::NetworkMemberFunctionBase(std::string name, const NetworkFunctionPointer& p):
+    NetworkFunctionBase(name)
+  {
+    RegisterObject(NetworkMemberFunctionBase);
+    
+    functorMap_[p] = this;
+    idMap_[ this->getNetworkID() ] = this;
+  }
+  
+  NetworkMemberFunctionBase::~NetworkMemberFunctionBase()
+  {
+  }
+  
+
+}
Index: code/branches/netp3/src/network/NetworkFunction.h
===================================================================
--- code/branches/netp3/src/network/NetworkFunction.h	(revision 2990)
+++ code/branches/netp3/src/network/NetworkFunction.h	(revision 2990)
@@ -0,0 +1,237 @@
+/*
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef NETWORKFUNCTION_H
+#define NETWORKFUNCTION_H
+
+#include "NetworkPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+#include <string>
+#include <map>
+#include <cassert>
+#include "util/MultiType.h"
+#include "synchronisable/Synchronisable.h"
+#include "OrxonoxConfig.h"
+#include "FunctionCallManager.h"
+
+
+namespace orxonox
+{
+
+#ifdef ORXONOX_COMPILER_GCC
+static const unsigned int MAX_FUNCTION_POINTER_SIZE = 8;
+#else //ORXONOX_COMPILER_GCC
+static const unsigned int MAX_FUNCTION_POINTER_SIZE = 16;
+#endif //ORXONOX_COMPILER_GCC
+static const unsigned int MAX_FUNCTION_POINTER_INTS = (MAX_FUNCTION_POINTER_SIZE-1)/4+1;
+
+struct _NetworkExport NetworkFunctionPointer {
+  uint32_t pointer[MAX_FUNCTION_POINTER_INTS];
+  bool operator<(const NetworkFunctionPointer& b) const
+  {
+#ifdef ORXONOX_COMPILER_GCC
+    return pointer[0]<b.pointer[0] ? true : pointer[1]<b.pointer[1];
+#else //ORXONOX_COMPILER_GCC
+    return pointer[0]<b.pointer[0] ? true : ( pointer[1]<b.pointer[1] ? true : ( pointer[2]<b.pointer[2] ? true : pointer[3]<b.pointer[3] ) );
+#endif //ORXONOX_COMPILER_GCC
+  }
+};
+
+
+
+
+
+class _NetworkExport NetworkFunctionBase: virtual public OrxonoxClass {
+  public:
+    NetworkFunctionBase(std::string name);
+    ~NetworkFunctionBase();
+    
+    inline void         setNetworkID(uint32_t id)       { this->networkID_ = id; }
+    inline uint32_t     getNetworkID() const            { return this->networkID_; }
+    inline std::string  getName() const                 { return name_; }
+    static inline bool  isStatic( uint32_t networkID )  { return isStaticMap_[networkID]; }
+    
+    static inline void setNetworkID(std::string name, uint32_t id){ assert( nameMap_.find(name)!=nameMap_.end() ); nameMap_[name]->setNetworkID(id); }
+    
+  protected:
+    static std::map<uint32_t, bool> isStaticMap_;
+    
+  private:
+    static std::map<std::string, NetworkFunctionBase*> nameMap_;
+    uint32_t networkID_;
+    std::string name_;
+      
+};
+
+
+class _NetworkExport NetworkFunctionStatic: public NetworkFunctionBase {
+  public:
+    NetworkFunctionStatic(FunctorStatic* functor, std::string name, const NetworkFunctionPointer& p);
+    ~NetworkFunctionStatic();
+    
+    inline void call(){ (*this->functor_)(); }
+    inline void call(const MultiType& mt1){ (*this->functor_)(mt1); }
+    inline void call(const MultiType& mt1, const MultiType& mt2){ (*this->functor_)(mt1, mt2); }
+    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3){ (*this->functor_)(mt1, mt2, mt3); }
+    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4){ (*this->functor_)(mt1, mt2, mt3, mt4); }
+    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5){ (*this->functor_)(mt1, mt2, mt3, mt4, mt5); }
+    
+    static inline NetworkFunctionStatic* getNetworkFunction( uint32_t id){ assert( idMap_.find(id)!=idMap_.end() ); return idMap_[id]; }
+    static NetworkFunctionStatic* getFunction( uint32_t id ){ assert( idMap_.find(id) != idMap_.end() ); return idMap_[id]; }
+    static NetworkFunctionStatic* getFunction( const NetworkFunctionPointer& p ){ assert( functorMap_.find(p) != functorMap_.end() ); return functorMap_[p]; }
+    
+  private:
+    static std::map<NetworkFunctionPointer, NetworkFunctionStatic*> functorMap_;
+    static std::map<uint32_t, NetworkFunctionStatic*> idMap_;
+    
+    FunctorStatic* functor_;
+    
+};
+
+
+class _NetworkExport NetworkMemberFunctionBase: public NetworkFunctionBase {
+  public:
+    NetworkMemberFunctionBase(std::string name, const NetworkFunctionPointer& p);
+    ~NetworkMemberFunctionBase();
+    
+    static inline NetworkMemberFunctionBase* getNetworkFunction( uint32_t id){ assert( idMap_.find(id)!=idMap_.end() ); return idMap_[id]; }
+    static NetworkMemberFunctionBase* getFunction( uint32_t id ){ assert( idMap_.find(id) != idMap_.end() ); return idMap_[id]; }
+    static NetworkMemberFunctionBase* getFunction( const NetworkFunctionPointer& p ){ assert( functorMap_.find(p) != functorMap_.end() ); return functorMap_[p]; }
+    
+    // 
+    virtual void call(uint32_t objectID)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)=0;
+    
+  private:
+    static std::map<NetworkFunctionPointer, NetworkMemberFunctionBase*> functorMap_;
+    static std::map<uint32_t, NetworkMemberFunctionBase*> idMap_;
+};
+
+
+template <class T> class _NetworkExport NetworkMemberFunction: public NetworkMemberFunctionBase {
+  public:
+    NetworkMemberFunction(FunctorMember<T>* functor, std::string name, const NetworkFunctionPointer& p);
+    ~NetworkMemberFunction();
+    
+    inline void call(uint32_t objectID)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)));
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3, mt4);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(dynamic_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3, mt4, mt5);
+    }
+    
+  private:
+    FunctorMember<T>* functor_;
+};
+
+template <class T> NetworkMemberFunction<T>::NetworkMemberFunction(FunctorMember<T>* functor, std::string name, const NetworkFunctionPointer& p):
+    NetworkMemberFunctionBase(name, p), functor_(functor)
+{
+}
+template <class T> NetworkMemberFunction<T>::~NetworkMemberFunction()
+{
+  delete this->functor_;
+}
+
+template<class T> inline void copyPtr( T ptr, NetworkFunctionPointer& destptr)
+{
+  memset((uint8_t*)&destptr + sizeof(T), 0, sizeof(NetworkFunctionPointer)-sizeof(T));
+  T p2 = ptr;
+  memcpy( &destptr, &p2, sizeof(T) );
+//   for(unsigned int i=0; i<(sizeof(T)-1/4)+1; i++)
+//     *((uint32_t*)destptr+i) = p2>>32*i;
+}
+
+template<class T> inline void* registerStaticNetworkFunctionFct( T ptr, std::string name )
+{
+  NetworkFunctionPointer destptr;
+  copyPtr( ptr, destptr );
+  new NetworkFunctionStatic( createFunctor(ptr), name, destptr );
+  return 0;
+}
+
+template<class T, class PT> inline void* registerMemberNetworkFunctionFct( PT ptr, std::string name )
+{
+  NetworkFunctionPointer destptr;
+  copyPtr( ptr, destptr );
+  new NetworkMemberFunction<T>( createFunctor(ptr), name, destptr );
+  return 0;
+}
+
+#define registerStaticNetworkFunction( functionPointer ) \
+  static void* MACRO_CONCATENATE( NETWORK_FUNCTION_, __LINE__ ) = registerStaticNetworkFunctionFct( functionPointer, #functionPointer );
+#define registerMemberNetworkFunction( class, function ) \
+  static void* MACRO_CONCATENATE( NETWORK_FUNCTION_##class, __LINE__ ) = registerMemberNetworkFunctionFct<class>( &class::function, #class "_" #function);
+  // call it with functionPointer, clientID, args
+#define callStaticNetworkFunction( functionPointer, ...) \
+  { \
+    NetworkFunctionPointer p1; \
+    copyPtr( functionPointer, p1 ); \
+    FunctionCallManager::addCallStatic(NetworkFunctionStatic::getFunction(p1)->getNetworkID(), __VA_ARGS__); \
+  }
+  // call it with class, function, objectID, clientID, args
+#define callMemberNetworkFunction( class, function, objectID, ...) \
+  { \
+    NetworkFunctionPointer p1; \
+    copyPtr( &class::function, p1 ); \
+    FunctionCallManager::addCallMember(NetworkMemberFunctionBase::getFunction(p1)->getNetworkID(), objectID, __VA_ARGS__); \
+  }
+
+
+}
+
+#endif
Index: code/branches/netp3/src/network/NetworkPrereqs.h
===================================================================
--- code/branches/netp3/src/network/NetworkPrereqs.h	(revision 2989)
+++ code/branches/netp3/src/network/NetworkPrereqs.h	(revision 2990)
@@ -90,4 +90,5 @@
   class ClientInformation;
   class ConnectionManager;
+  class FunctionCallManager;
   class GamestateClient;
   class GamestateManager;
@@ -96,4 +97,9 @@
   template <class T> class NetworkCallback;
   class NetworkCallbackManager;
+  class NetworkFunctionBase;
+  class NetworkFunctionStatic;
+  class NetworkMemberFunctionBase;
+  template <class T> class NetworkMemeberFunction;
+  struct NetworkFunctionPointer;
   class PacketBuffer;
   class Server;
@@ -112,10 +118,13 @@
   namespace packet
   {
+    class Acknowledgement;
+    class Chat;
+    class ClassID;
+    class FunctionCalls;
+    class FunctionIDs;
     class Gamestate;
+    class NetworkIDs;
     class Packet;
-    class Acknowledgement;
-    class ClassID;
     class Welcome;
-    class Chat;
   }
 }
Index: code/branches/netp3/src/network/Server.cc
===================================================================
--- code/branches/netp3/src/network/Server.cc	(revision 2989)
+++ code/branches/netp3/src/network/Server.cc	(revision 2990)
@@ -61,4 +61,7 @@
 #include "util/Convert.h"
 #include "ChatListener.h"
+#include "FunctionCallManager.h"
+#include "packet/FunctionIDs.h"
+
 
 namespace orxonox
@@ -158,4 +161,5 @@
       gamestates_->processGamestates();
       updateGamestate();
+      FunctionCallManager::sendCalls();
     }
   }
@@ -341,11 +345,20 @@
       return false;
     }
-    COUT(4) << "Con.Man: creating client id: " << temp->getID() << std::endl;
+    COUT(5) << "Con.Man: creating client id: " << temp->getID() << std::endl;
+    
+    // synchronise class ids
     connection->syncClassid(temp->getID());
+    
+    // now synchronise functionIDs
+    packet::FunctionIDs *fIDs = new packet::FunctionIDs();
+    fIDs->setClientID(clientID);
+    bool b = fIDs->send();
+    assert(b);
+    
     temp->setSynched(true);
-    COUT(3) << "sending welcome" << std::endl;
+    COUT(4) << "sending welcome" << std::endl;
     packet::Welcome *w = new packet::Welcome(temp->getID(), temp->getShipID());
     w->setClientID(temp->getID());
-    bool b = w->send();
+    b = w->send();
     assert(b);
     packet::Gamestate *g = new packet::Gamestate();
Index: code/branches/netp3/src/network/Server.h
===================================================================
--- code/branches/netp3/src/network/Server.h	(revision 2989)
+++ code/branches/netp3/src/network/Server.h	(revision 2990)
@@ -51,7 +51,4 @@
 namespace orxonox
 {
-  const int CLIENTID_SERVER = 0;
-  const unsigned int NETWORK_FREQUENCY = 25;
-  const float NETWORK_PERIOD = 1.f/NETWORK_FREQUENCY;
 
   /**
Index: code/branches/netp3/src/network/TrafficControl.cc
===================================================================
--- code/branches/netp3/src/network/TrafficControl.cc	(revision 2989)
+++ code/branches/netp3/src/network/TrafficControl.cc	(revision 2990)
@@ -91,6 +91,6 @@
   void TrafficControl::setConfigValues()
   {
-    SetConfigValue ( bActive_, true );
-    SetConfigValue ( targetSize, 5000 );
+    SetConfigValue ( bActive_, false );
+    SetConfigValue ( targetSize, 10000 );
   }
 
Index: code/branches/netp3/src/network/packet/CMakeLists.txt
===================================================================
--- code/branches/netp3/src/network/packet/CMakeLists.txt	(revision 2989)
+++ code/branches/netp3/src/network/packet/CMakeLists.txt	(revision 2990)
@@ -1,9 +1,11 @@
 ADD_SOURCE_FILES(NETWORK_SRC_FILES
   Packet.cc
+  Acknowledgement.cc
   Chat.cc
   ClassID.cc
-  Acknowledgement.cc
+  DeleteObjects.cc
+  FunctionIDs.cc
+  FunctionCalls.cc
   Gamestate.cc
   Welcome.cc
-  DeleteObjects.cc
 )
Index: code/branches/netp3/src/network/packet/ClassID.cc
===================================================================
--- code/branches/netp3/src/network/packet/ClassID.cc	(revision 2989)
+++ code/branches/netp3/src/network/packet/ClassID.cc	(revision 2990)
@@ -93,5 +93,5 @@
   }
   
-  COUT(0) << "classid packetSize is " << packetSize << endl;
+  COUT(5) << "classid packetSize is " << packetSize << endl;
   
 }
Index: code/branches/netp3/src/network/packet/FunctionCalls.cc
===================================================================
--- code/branches/netp3/src/network/packet/FunctionCalls.cc	(revision 2990)
+++ code/branches/netp3/src/network/packet/FunctionCalls.cc	(revision 2990)
@@ -0,0 +1,323 @@
+/*
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FunctionCalls.h"
+
+#include <enet/enet.h>
+#include <cassert>
+#include <cstring>
+#include "network/Host.h"
+#include "network/NetworkFunction.h"
+#include "util/MultiType.h"
+
+namespace orxonox {
+namespace packet {
+  
+#define   PACKET_FLAGS_FUNCTIONCALLS ENET_PACKET_FLAG_RELIABLE
+#define   _PACKETID         0
+const unsigned int FUNCTIONCALLS_MEM_ALLOCATION = 1000;
+    
+FunctionCalls::FunctionCalls()
+ : Packet()
+{
+  flags_ = flags_ | PACKET_FLAGS_FUNCTIONCALLS;
+  currentSize_ = 2*sizeof(uint32_t); // for packetid and nrOfCalls
+  nrOfCalls_ = 0;
+  currentMemBlocks_ = 1;
+  data_=new uint8_t[ FUNCTIONCALLS_MEM_ALLOCATION ];
+  *(ENUM::Type *)(data_ + _PACKETID ) = ENUM::FunctionCalls;
+  *(uint32_t*)(data_+sizeof(uint32_t)) = 0; // set nrOfCalls to 0
+}
+
+FunctionCalls::FunctionCalls( uint8_t* data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+FunctionCalls::~FunctionCalls()
+{
+}
+
+
+bool FunctionCalls::process(){
+  assert(isDataENetAllocated());
+  uint8_t* temp = data_+sizeof(uint32_t); //skip packetid
+  this->nrOfCalls_ = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  for( unsigned int i = 0; i<this->nrOfCalls_; i++ )
+  {
+    uint32_t functionID = *(uint32_t*)temp;
+    bool isStatic = *(uint8_t*)(temp+sizeof(uint32_t));
+    if( isStatic )
+    {
+      MultiType mt1, mt2, mt3, mt4, mt5;
+      NetworkFunctionStatic *fct = NetworkFunctionStatic::getFunction( functionID );
+      uint32_t nrOfArguments = *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t));
+      temp+=2*sizeof(uint32_t)+sizeof(uint8_t);
+      switch(nrOfArguments)
+      {
+        case 0:
+          fct->call();
+          break;
+        case 1:
+          mt1.importData(temp);
+          fct->call(mt1);
+          break;
+        case 2:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          fct->call(mt1, mt2);
+          break;
+        case 3:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          fct->call(mt1, mt2, mt3);
+          break;
+        case 4:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          fct->call(mt1, mt2, mt3, mt4);
+          break;
+        case 5:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          mt5.importData(temp);
+          fct->call(mt1, mt2, mt3, mt4, mt5);
+          break;
+        default:
+          assert(0);
+      }
+    }
+    else // not a static function, so also handle the objectID
+    {
+      MultiType mt1, mt2, mt3, mt4, mt5;
+      NetworkMemberFunctionBase *fct = NetworkMemberFunctionBase::getFunction( functionID );
+      uint32_t nrOfArguments = *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t));
+      uint32_t objectID = *(uint32_t*)(temp+2*sizeof(uint32_t)+sizeof(uint8_t));
+      temp+=3*sizeof(uint32_t)+sizeof(uint8_t);
+      switch(nrOfArguments)
+      {
+        case 0:
+          fct->call(objectID);
+          break;
+        case 1:
+          mt1.importData(temp);
+          fct->call(objectID, mt1);
+          break;
+        case 2:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          fct->call(objectID, mt1, mt2);
+          break;
+        case 3:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          fct->call(objectID, mt1, mt2, mt3);
+          break;
+        case 4:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          fct->call(objectID, mt1, mt2, mt3, mt4);
+          break;
+        case 5:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          mt5.importData(temp);
+          fct->call(objectID, mt1, mt2, mt3, mt4, mt5);
+          break;
+        default:
+          assert(0);
+          break;
+      }
+    }
+  }
+  delete this;
+  return true;
+}
+
+void FunctionCalls::addCallStatic( uint32_t networkID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
+  assert(!isDataENetAllocated());
+  
+  // first determine the size that has to be reserved for this call
+  uint32_t callsize = 2*sizeof(uint32_t)+sizeof(uint8_t); //size for network-function-id and nrOfArguments and for bool isStatic
+  uint32_t nrOfArguments = 0;
+  if(mt1)
+  {
+    nrOfArguments++;
+    callsize += mt1->getNetworkSize();
+    if(mt2)
+    {
+      nrOfArguments++;
+      callsize += mt2->getNetworkSize();
+      if(mt3)
+      {
+        nrOfArguments++;
+        callsize += mt3->getNetworkSize();
+        if(mt4)
+        {
+          nrOfArguments++;
+          callsize += mt4->getNetworkSize();
+          if(mt5)
+          {
+            nrOfArguments++;
+            callsize += mt5->getNetworkSize();
+          }
+        }
+      }
+    }
+  }
+  
+  // now allocated mem if neccessary
+  if( currentSize_ + callsize > currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION )
+  {
+    currentMemBlocks_ = (currentSize_ + callsize)%FUNCTIONCALLS_MEM_ALLOCATION+1;
+    uint8_t *temp = new uint8_t[currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION];
+    memcpy( temp, data_, currentSize_ );
+    delete[] data_;
+    data_ = temp;
+  }
+  
+  // now serialise the mt values and copy the function id and isStatic
+  uint8_t* temp = data_+currentSize_;
+  *(uint32_t*)(data_+sizeof(uint32_t)) = *(uint32_t*)(data_+sizeof(uint32_t))+1; // increase number of calls
+  *(uint32_t*)temp = networkID;
+  *(uint8_t*)(temp+sizeof(uint32_t)) = true;
+  *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t)) = nrOfArguments;
+  temp += 2*sizeof(uint32_t)+sizeof(uint8_t);
+  if(mt1)
+  {
+    mt1->exportData( temp ); //temp gets automatically increased
+    if(mt2)
+    {
+      mt2->exportData( temp ); //temp gets automatically increased
+      if(mt3)
+      {
+        mt3->exportData( temp ); //temp gets automatically increased
+        if(mt4)
+        {
+          mt4->exportData( temp ); //temp gets automatically increased
+          if(mt5)
+          {
+            mt5->exportData( temp ); //temp gets automatically increased
+          }
+        }
+      }
+    }
+  }
+  //currentSize_ += callsize;
+  currentSize_ = temp-data_;
+  
+}
+
+void FunctionCalls::addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
+  assert(!isDataENetAllocated());
+  
+  // first determine the size that has to be reserved for this call
+  uint32_t callsize = 3*sizeof(uint32_t)+sizeof(uint8_t); //size for network-function-id and nrOfArguments and the objectID
+  uint32_t nrOfArguments = 0;
+  if(mt1)
+  {
+    nrOfArguments++;
+    callsize += mt1->getNetworkSize();
+    if(mt2)
+    {
+      nrOfArguments++;
+      callsize += mt2->getNetworkSize();
+      if(mt3)
+      {
+        nrOfArguments++;
+        callsize += mt3->getNetworkSize();
+        if(mt4)
+        {
+          nrOfArguments++;
+          callsize += mt4->getNetworkSize();
+          if(mt5)
+          {
+            nrOfArguments++;
+            callsize += mt5->getNetworkSize();
+          }
+        }
+      }
+    }
+  }
+  
+  // now allocated mem if neccessary
+  if( currentSize_ + callsize > currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION )
+  {
+    currentMemBlocks_ = (currentSize_ + callsize)%FUNCTIONCALLS_MEM_ALLOCATION+1;
+    uint8_t *temp = new uint8_t[currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION];
+    memcpy( temp, data_, currentSize_ );
+    delete[] data_;
+    data_ = temp;
+  }
+  
+  // now serialise the mt values and copy the function id
+  uint8_t* temp = data_+currentSize_;
+  *(uint32_t*)(data_+sizeof(uint32_t)) = *(uint32_t*)(data_+sizeof(uint32_t))+1; // increase number of calls
+  *(uint32_t*)temp = networkID;
+  *(uint8_t*)(temp+sizeof(uint32_t)) = false;
+  *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t)) = nrOfArguments;
+  *(uint32_t*)(temp+2*sizeof(uint32_t)+sizeof(uint8_t)) = objectID;
+  temp += 3*sizeof(uint32_t)+sizeof(uint8_t);
+  if(mt1)
+  {
+    mt1->exportData( temp ); //temp gets automatically increased
+    if(mt2)
+    {
+      mt2->exportData( temp ); //temp gets automatically increased
+      if(mt3)
+      {
+        mt3->exportData( temp ); //temp gets automatically increased
+        if(mt4)
+        {
+          mt4->exportData( temp ); //temp gets automatically increased
+          if(mt5)
+          {
+            mt5->exportData( temp ); //temp gets automatically increased
+          }
+        }
+      }
+    }
+  }
+  currentSize_ += callsize;
+  
+}
+
+
+} //namespace packet
+} //namespace orxonox
Index: code/branches/netp3/src/network/packet/FunctionCalls.h
===================================================================
--- code/branches/netp3/src/network/packet/FunctionCalls.h	(revision 2990)
+++ code/branches/netp3/src/network/packet/FunctionCalls.h	(revision 2990)
@@ -0,0 +1,46 @@
+
+#ifndef NETWORKFUNCTIONCALLS_H
+#define NETWORKFUNCTIONCALLS_H
+
+#include "../NetworkPrereqs.h"
+
+#include <string>
+#include <cstring>
+
+#include "Packet.h"
+#include <cassert>
+
+namespace orxonox {
+
+class MultiType;
+
+namespace packet {
+/**
+	@author
+*/
+
+
+class _NetworkExport FunctionCalls : public Packet
+{
+public:
+  FunctionCalls();
+  FunctionCalls( uint8_t* data, unsigned int clientID );
+  ~FunctionCalls();
+
+  inline unsigned int getSize() const
+    { assert(!this->isDataENetAllocated()); return currentSize_; }
+  bool process();
+
+  void addCallStatic( uint32_t networkID, const MultiType* mt1=0, const MultiType* mt2=0, const MultiType* mt3=0, const MultiType* mt4=0, const MultiType* mt5=0);
+  void addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1=0, const MultiType* mt2=0, const MultiType* mt3=0, const MultiType* mt4=0, const MultiType* mt5=0);
+private:
+  uint32_t nrOfCalls_;
+  unsigned int clientID_;
+  uint32_t currentSize_;
+  uint32_t currentMemBlocks_; // this saves the number of memory blocks (of size FUNCTIONCALLS_MEM_ALLOCATION) allocated
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif
Index: code/branches/netp3/src/network/packet/FunctionIDs.cc
===================================================================
--- code/branches/netp3/src/network/packet/FunctionIDs.cc	(revision 2990)
+++ code/branches/netp3/src/network/packet/FunctionIDs.cc	(revision 2990)
@@ -0,0 +1,143 @@
+/*
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+
+#include "FunctionIDs.h"
+#include "network/NetworkFunction.h"
+#include <enet/enet.h>
+#include "core/CoreIncludes.h"
+#include <string>
+#include <cassert>
+#include <queue>
+
+namespace orxonox {
+namespace packet {
+
+
+#define PACKET_FLAGS_FUNCTIONIDS  ENET_PACKET_FLAG_RELIABLE
+#define _PACKETID                 0
+
+
+FunctionIDs::FunctionIDs( ) : Packet(){
+  std::string functionname;
+  unsigned int nrOfFunctions=0; 
+  unsigned int packetSize=2*sizeof(uint32_t); //space for the packetID and for the nroffunctions
+  uint32_t networkID;
+  flags_ = flags_ | PACKET_FLAGS_FUNCTIONIDS;
+  std::queue<std::pair<uint32_t, std::string> > tempQueue;
+  
+  //calculate total needed size (for all strings and integers)
+  ObjectList<NetworkFunctionBase>::iterator it;
+  for(it = ObjectList<NetworkFunctionBase>::begin(); it; ++it){
+    functionname = it->getName();
+    networkID = it->getNetworkID();
+    // now push the network id and the classname to the stack
+    tempQueue.push( std::pair<unsigned int, std::string>(networkID, functionname) );
+    ++nrOfFunctions;
+    packetSize += (functionname.size()+1)+sizeof(uint32_t)+sizeof(uint32_t); // reserver size for the functionname string, the functionname length and the networkID
+  }
+  
+  this->data_=new uint8_t[ packetSize ];
+  //set the appropriate packet id
+  assert(this->data_);
+  *(ENUM::Type *)(this->data_ + _PACKETID ) = ENUM::FunctionIDs;
+  
+  uint8_t *temp=data_+sizeof(uint32_t);
+  // save the number of all classes
+  *(uint32_t*)temp = nrOfFunctions;
+  temp += sizeof(uint32_t);
+  
+  // now save all classids and classnames
+  std::pair<uint32_t, std::string> tempPair;
+  while( !tempQueue.empty() ){
+    tempPair = tempQueue.front();
+    tempQueue.pop();
+    *(uint32_t*)temp = tempPair.first;
+    *(uint32_t*)(temp+sizeof(uint32_t)) = tempPair.second.size()+1;
+    memcpy(temp+2*sizeof(uint32_t), tempPair.second.c_str(), tempPair.second.size()+1);
+    temp+=2*sizeof(uint32_t)+tempPair.second.size()+1;
+  }
+  
+  COUT(5) << "FunctionIDs packetSize is " << packetSize << endl;
+  
+}
+
+FunctionIDs::FunctionIDs( uint8_t* data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+FunctionIDs::~FunctionIDs()
+{
+}
+
+uint32_t FunctionIDs::getSize() const{
+  assert(this->data_);
+  uint8_t *temp = data_+sizeof(uint32_t); // packet identification
+  uint32_t totalsize = sizeof(uint32_t); // data size
+  uint32_t nrOfFunctions = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  totalsize += sizeof(uint32_t); // storage size for nr of all classes
+  
+  for(unsigned int i=0; i<nrOfFunctions; i++){
+    totalsize += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t)); // for each network function add size for id, sizeof(string) and length of string itself to totalsize
+    temp += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t));
+  }
+  return totalsize;
+}
+
+
+bool FunctionIDs::process(){
+  int nrOfFunctions;
+  uint8_t *temp = data_+sizeof(uint32_t); //skip the packetid
+  uint32_t networkID;
+  uint32_t stringsize;
+  unsigned char *functionname;
+  
+  COUT(4) << "=== processing functionids: " << endl;
+  std::pair<uint32_t, std::string> tempPair;
+  // read the total number of classes
+  nrOfFunctions = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  
+  for( int i=0; i<nrOfFunctions; i++){
+    networkID = *(uint32_t*)temp;
+    stringsize = *(uint32_t*)(temp+sizeof(uint32_t));
+    functionname = temp+2*sizeof(uint32_t);
+    COUT(0) << "processing functionid: " << networkID << " name: " << functionname << std::endl;
+    NetworkFunctionBase::setNetworkID((const char*)functionname, networkID);
+    temp += 2*sizeof(uint32_t) + stringsize;
+  }
+  delete this;
+  return true;
+}
+
+
+} //namespace packet
+}//namespace orxonox
Index: code/branches/netp3/src/network/packet/FunctionIDs.h
===================================================================
--- code/branches/netp3/src/network/packet/FunctionIDs.h	(revision 2990)
+++ code/branches/netp3/src/network/packet/FunctionIDs.h	(revision 2990)
@@ -0,0 +1,60 @@
+/*
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+ */
+#ifndef NETWORKFUNCTIONIDS_H
+#define NETWORKFUNCTIONIDS_H
+
+#include "../NetworkPrereqs.h"
+
+#include <string>
+
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+
+  
+/**
+	@author
+*/
+class _NetworkExport FunctionIDs : public Packet
+{
+public:
+  FunctionIDs( );
+  FunctionIDs( uint8_t* data, unsigned int clientID );
+  ~FunctionIDs();
+
+  uint32_t getSize() const;
+  bool process();
+
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif
Index: code/branches/netp3/src/network/packet/Gamestate.cc
===================================================================
--- code/branches/netp3/src/network/packet/Gamestate.cc	(revision 2989)
+++ code/branches/netp3/src/network/packet/Gamestate.cc	(revision 2990)
@@ -107,5 +107,10 @@
   for(it = ObjectList<Synchronisable>::begin(); it; ++it){
     
-    tempsize=it->getSize(id, mode);
+//     tempsize=it->getSize(id, mode);
+
+    tempsize = it->getData(mem, id, mode);
+    if ( it->doSync( id, mode ) )
+      dataMap_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) );
+    
 #ifndef NDEBUG
     if(currentsize+tempsize > size){
@@ -123,9 +128,6 @@
     }// stop allocate additional memory
 #endif
-
-    if ( it->doSync( id, mode ) )
-      dataMap_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) );
-    if(!it->getData(mem, id, mode))
-      return false; // mem pointer gets automatically increased because of call by reference
+//     if(!it->getData(mem, id, mode))
+//       return false; // mem pointer gets automatically increased because of call by reference
     // increase size counter by size of current synchronisable
     currentsize+=tempsize;
Index: code/branches/netp3/src/network/packet/Packet.cc
===================================================================
--- code/branches/netp3/src/network/packet/Packet.cc	(revision 2989)
+++ code/branches/netp3/src/network/packet/Packet.cc	(revision 2990)
@@ -39,9 +39,11 @@
 
 #include "Acknowledgement.h"
+#include "DeleteObjects.h"
 #include "Chat.h"
 #include "ClassID.h"
+#include "FunctionCalls.h"
+#include "FunctionIDs.h"
 #include "Gamestate.h"
 #include "Welcome.h"
-#include "DeleteObjects.h"
 #include "network/Host.h"
 #include "core/CoreIncludes.h"
@@ -153,4 +155,6 @@
     case ENUM::Welcome:
     case ENUM::DeleteObjects:
+    case ENUM::FunctionIDs:
+    case ENUM::FunctionCalls:
       break;
     default:
@@ -170,31 +174,39 @@
   unsigned int clientID = ClientInformation::findClient(&peer->address)->getID();
   Packet *p = 0;
-  COUT(5) << "packet type: " << *(ENUM::Type *)&data[_PACKETID] << std::endl;
+  COUT(6) << "packet type: " << *(ENUM::Type *)&data[_PACKETID] << std::endl;
   switch( *(ENUM::Type *)(data + _PACKETID) )
   {
     case ENUM::Acknowledgement:
-      COUT(4) << "ack" << std::endl;
+      COUT(5) << "ack" << std::endl;
       p = new Acknowledgement( data, clientID );
       break;
     case ENUM::Chat:
-      COUT(4) << "chat" << std::endl;
+      COUT(5) << "chat" << std::endl;
       p = new Chat( data, clientID );
       break;
     case ENUM::ClassID:
-      COUT(4) << "classid" << std::endl;
+      COUT(5) << "classid" << std::endl;
       p = new ClassID( data, clientID );
       break;
     case ENUM::Gamestate:
-      COUT(4) << "gamestate" << std::endl;
+      COUT(5) << "gamestate" << std::endl;
       // TODO: remove brackets
       p = new Gamestate( data, clientID );
       break;
     case ENUM::Welcome:
-      COUT(4) << "welcome" << std::endl;
+      COUT(5) << "welcome" << std::endl;
       p = new Welcome( data, clientID );
       break;
     case ENUM::DeleteObjects:
-      COUT(4) << "deleteobjects" << std::endl;
+      COUT(5) << "deleteobjects" << std::endl;
       p = new DeleteObjects( data, clientID );
+      break;
+    case ENUM::FunctionCalls:
+      COUT(5) << "functionCalls" << std::endl;
+      p = new FunctionCalls( data, clientID );
+      break;
+    case ENUM::FunctionIDs:
+      COUT(5) << "functionIDs" << std::endl;
+      p = new FunctionIDs( data, clientID );
       break;
     default:
Index: code/branches/netp3/src/network/packet/Packet.h
===================================================================
--- code/branches/netp3/src/network/packet/Packet.h	(revision 2989)
+++ code/branches/netp3/src/network/packet/Packet.h	(revision 2990)
@@ -45,9 +45,11 @@
   enum Type{
     Acknowledgement,
+    Chat,
+    ClassID,
+    DeleteObjects,
+    FunctionIDs,
+    FunctionCalls,
     Gamestate,
-    ClassID,
-    Chat,
-    Welcome,
-    DeleteObjects
+    Welcome
   };
 }
@@ -66,9 +68,9 @@
     virtual unsigned int getSize() const =0;
     virtual bool process()=0;
-    uint32_t getFlags()
+    inline uint32_t getFlags()
       { return flags_; }
-    int getClientID()
+    inline int getClientID()
       { return clientID_; }
-    void setClientID( int id )
+    inline void setClientID( int id )
       { clientID_ = id; }
 
@@ -78,4 +80,7 @@
     Packet(uint8_t *data, unsigned int clientID);
 //    Packet(ENetPacket *packet, ENetPeer *peer);
+    inline bool isDataENetAllocated() const
+      { return bDataENetAllocated_; }
+
     uint32_t flags_;
     unsigned int clientID_;
Index: code/branches/netp3/src/network/synchronisable/NetworkCallbackManager.cc
===================================================================
--- code/branches/netp3/src/network/synchronisable/NetworkCallbackManager.cc	(revision 2989)
+++ code/branches/netp3/src/network/synchronisable/NetworkCallbackManager.cc	(revision 2990)
@@ -32,5 +32,5 @@
 
 namespace orxonox{
-
+  
   std::set<NetworkCallbackBase*> NetworkCallbackManager::callbackSet_;
   std::queue<NetworkCallbackBase*> NetworkCallbackManager::triggeredCallbacks_;
@@ -60,5 +60,7 @@
     while( triggeredCallbacks_.empty()==false )
     {
-      triggeredCallbacks_.front()->call();
+      //make sure callback hasn't been deleted before
+      if ( callbackSet_.find(triggeredCallbacks_.front()) != callbackSet_.end() )
+        triggeredCallbacks_.front()->call();
       triggeredCallbacks_.pop();
     }
Index: code/branches/netp3/src/network/synchronisable/Synchronisable.cc
===================================================================
--- code/branches/netp3/src/network/synchronisable/Synchronisable.cc	(revision 2989)
+++ code/branches/netp3/src/network/synchronisable/Synchronisable.cc	(revision 2990)
@@ -66,5 +66,7 @@
       objectID=OBJECTID_UNKNOWN;
     classID = static_cast<uint32_t>(-1);
-
+    
+    // set dataSize to 0
+    this->dataSize_ = 0;
     // set standard priority
     this->setPriority( priority::normal );
@@ -96,5 +98,5 @@
     // delete callback function objects
     if(!Identifier::isCreatingHierarchy()){
-      for(std::list<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
+      for(std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
         delete (*it);
       if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
@@ -236,10 +238,10 @@
    * @return true: if !doSync or if everything was successfully saved
    */
-  bool Synchronisable::getData(uint8_t*& mem, int32_t id, uint8_t mode){
+  uint32_t Synchronisable::getData(uint8_t*& mem, int32_t id, uint8_t mode){
     if(mode==0x0)
       mode=state_;
     //if this tick is we dont synchronise, then abort now
     if(!doSync(id, mode))
-      return true;
+      return 0;
     uint32_t tempsize = 0;
     if (this->classID==0)
@@ -250,28 +252,32 @@
 
     assert(this->classID==this->getIdentifier()->getNetworkID());
-    std::list<SynchronisableVariableBase*>::iterator i;
-    uint32_t size;
-    size=getSize(id, mode);
+    std::vector<SynchronisableVariableBase*>::iterator i;
 
     // start copy header
     SynchronisableHeader header(mem);
-    header.setDataSize( size );
+    mem += SynchronisableHeader::getSize();
+    // end copy header
+
+
+    COUT(5) << "Synchronisable getting data from objectID: " << objectID << " classID: " << classID << std::endl;
+    // copy to location
+    for(i=syncList.begin(); i!=syncList.end(); ++i){
+      tempsize += (*i)->getData( mem, mode );
+      //tempsize += (*i)->getSize( mode );
+    }
+    
+    tempsize += SynchronisableHeader::getSize();
     header.setObjectID( this->objectID );
     header.setCreatorID( this->creatorID );
     header.setClassID( this->classID );
     header.setDataAvailable( true );
-    tempsize += SynchronisableHeader::getSize();
-    mem += SynchronisableHeader::getSize();
-    // end copy header
-
-
-    COUT(5) << "Synchronisable getting data from objectID: " << objectID << " classID: " << classID << " length: " << size << std::endl;
-    // copy to location
-    for(i=syncList.begin(); i!=syncList.end(); ++i){
-      (*i)->getData( mem, mode );
-      tempsize += (*i)->getSize( mode );
-    }
+    header.setDataSize( tempsize );
+    
+#ifndef NDEBUG
+    uint32_t size;
+    size=getSize(id, mode);
     assert(tempsize==size);
-    return true;
+#endif
+    return tempsize;
   }
 
@@ -286,5 +292,5 @@
     if(mode==0x0)
       mode=state_;
-    std::list<SynchronisableVariableBase *>::iterator i;
+    std::vector<SynchronisableVariableBase *>::iterator i;
     if(syncList.empty()){
       assert(0);
@@ -325,10 +331,12 @@
   uint32_t Synchronisable::getSize(int32_t id, uint8_t mode){
     int tsize=SynchronisableHeader::getSize();
-    if(mode==0x0)
+    if (mode==0x0)
       mode=state_;
-    if(!doSync(id, mode))
+    if (!doSync(id, mode))
       return 0;
-    std::list<SynchronisableVariableBase*>::iterator i;
-    for(i=syncList.begin(); i!=syncList.end(); i++){
+    assert( mode==state_ );
+    tsize += this->dataSize_;
+    std::vector<SynchronisableVariableBase*>::iterator i;
+    for(i=stringList.begin(); i!=stringList.end(); ++i){
       tsize += (*i)->getSize( mode );
     }
Index: code/branches/netp3/src/network/synchronisable/Synchronisable.h
===================================================================
--- code/branches/netp3/src/network/synchronisable/Synchronisable.h	(revision 2989)
+++ code/branches/netp3/src/network/synchronisable/Synchronisable.h	(revision 2990)
@@ -33,7 +33,9 @@
 
 #include <list>
+#include <vector>
 #include <map>
 #include <queue>
 #include <cassert>
+#include <string>
 #include "util/Math.h"
 #include "util/mbool.h"
@@ -120,5 +122,4 @@
   public:
     friend class packet::Gamestate;
-//     friend class Server;
     virtual ~Synchronisable();
 
@@ -139,5 +140,5 @@
     Synchronisable(BaseObject* creator);
     template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
-    template <class T> void unregisterVariable(T& var);
+    //template <class T> void unregisterVariable(T& var);
     void setObjectMode(uint8_t mode);
     void setPriority(unsigned int freq){ objectFrequency_ = freq; }
@@ -145,5 +146,5 @@
 
   private:
-    bool getData(uint8_t*& men, int32_t id, uint8_t mode=0x0);
+    uint32_t getData(uint8_t*& men, int32_t id, uint8_t mode=0x0);
     uint32_t getSize(int32_t id, uint8_t mode=0x0);
     bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
@@ -155,5 +156,7 @@
     uint32_t classID;
 
-    std::list<SynchronisableVariableBase*> syncList;
+    std::vector<SynchronisableVariableBase*> syncList;
+    std::vector<SynchronisableVariableBase*> stringList;
+    uint32_t dataSize_; //size of all variables except strings
     static uint8_t state_; // detemines wheter we are server (default) or client
     bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
@@ -164,29 +167,8 @@
   };
 
-  template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
-  {
-    if (bidirectional)
-      syncList.push_back(new SynchronisableVariableBidirectional<const T>(variable, mode, cb));
-    else
-      syncList.push_back(new SynchronisableVariable<const T>(variable, mode, cb));
-  }
-
-  template <class T> void Synchronisable::unregisterVariable(T& var){
-    std::list<SynchronisableVariableBase*>::iterator it = syncList.begin();
-    while(it!=syncList.end()){
-      if( ((*it)->getReference()) == &var ){
-        delete (*it);
-        syncList.erase(it);
-        return;
-      }
-      else
-        it++;
-    }
-    bool unregistered_nonexistent_variable = false;
-    assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
-    // the variable has not been registered before
-  }
-
   // ================= Specialisation declarations
+  
+//   template <> _NetworkExport void Synchronisable::registerVariable( const std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
   template <> _NetworkExport void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
   template <> _NetworkExport void Synchronisable::registerVariable( ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
@@ -200,4 +182,39 @@
   template <> _NetworkExport void Synchronisable::registerVariable( const Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
   template <> _NetworkExport void Synchronisable::registerVariable( Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  
+  template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
+  {
+    if (bidirectional)
+    {
+      syncList.push_back(new SynchronisableVariableBidirectional<const T>(variable, mode, cb));
+      this->dataSize_ += syncList.back()->getSize(state_);
+    }
+    else
+    {
+      syncList.push_back(new SynchronisableVariable<const T>(variable, mode, cb));
+      if ( this->state_ == mode )
+        this->dataSize_ += syncList.back()->getSize(state_);
+    }
+  }
+  
+
+
+//   template <class T> void Synchronisable::unregisterVariable(T& var){
+//     std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin();
+//     while(it!=syncList.end()){
+//       if( ((*it)->getReference()) == &var ){
+//         delete (*it);
+//         syncList.erase(it);
+//         return;
+//       }
+//       else
+//         it++;
+//     }
+//     bool unregistered_nonexistent_variable = false;
+//     assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
+//     // the variable has not been registered before
+//   }
+
+  
 }
 
Index: code/branches/netp3/src/network/synchronisable/SynchronisableSpecialisations.cc
===================================================================
--- code/branches/netp3/src/network/synchronisable/SynchronisableSpecialisations.cc	(revision 2989)
+++ code/branches/netp3/src/network/synchronisable/SynchronisableSpecialisations.cc	(revision 2990)
@@ -29,4 +29,5 @@
 
 #include "network/synchronisable/Synchronisable.h"
+#include <string>
 
 // ================ template spezialisation
@@ -34,4 +35,22 @@
   
 namespace orxonox{
+  
+//   template <> void Synchronisable::registerVariable( const std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
+//   {
+//     if (bidirectional)
+//       syncList.push_back(new SynchronisableVariableBidirectional<const std::string>(variable, mode, cb));
+//     else
+//       syncList.push_back(new SynchronisableVariable<const std::string>(variable, mode, cb));
+//     stringList.push_back(syncList.back());
+//   }
+  
+  template <> void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
+  {
+    if (bidirectional)
+      syncList.push_back(new SynchronisableVariableBidirectional<const std::string>(variable, mode, cb));
+    else
+      syncList.push_back(new SynchronisableVariable<const std::string>(variable, mode, cb));
+    stringList.push_back(syncList.back());
+  }
   
   template <> void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
@@ -52,8 +71,8 @@
     registerVariable(variable.y, mode, cb, bidirectional);
   }
-  template <> void Synchronisable::registerVariable( Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
-  {
-    registerVariable( (const ColourValue&)variable, mode, cb, bidirectional);
-  }
+//   template <> void Synchronisable::registerVariable( Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+//   {
+//     registerVariable( (const ColourValue&)variable, mode, cb, bidirectional);
+//   }
   
   template <> void Synchronisable::registerVariable( const Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
Index: code/branches/netp3/src/network/synchronisable/SynchronisableVariable.cc
===================================================================
--- code/branches/netp3/src/network/synchronisable/SynchronisableVariable.cc	(revision 2989)
+++ code/branches/netp3/src/network/synchronisable/SynchronisableVariable.cc	(revision 2990)
@@ -28,7 +28,4 @@
 
 #include "SynchronisableVariable.h"
-#include <cstring>
-#include "util/Math.h"
-#include "core/GameMode.h"
 
 
@@ -37,405 +34,3 @@
 uint8_t SynchronisableVariableBase::state_ = 0;
 
-/*static*/ void SynchronisableVariableBase::setState()
-{
-  if ( state_ == 0x0 )
-  {
-    state_ = GameMode::isMaster() ? 0x1 : 0x2;  // set the appropriate mode here
-  }
-}
-
-
-// =================== Template specialisation stuff =============
-
-// =========== bool
-
-template <> uint32_t SynchronisableVariable<const bool>::returnSize()
-{
-  return sizeof(uint8_t);
-}
-
-template <> void SynchronisableVariable<const bool>::setAndIncrease( uint8_t*& mem )
-{
-  *(uint8_t*)(&this->variable_) = *static_cast<uint8_t*>(mem);
-  mem += SynchronisableVariable<const bool>::returnSize();
-}
-
-template <> void SynchronisableVariable<const bool>::getAndIncrease( uint8_t*& mem )
-{
-  *static_cast<uint8_t*>(mem) = *(uint8_t*)(&this->variable_);
-  mem += SynchronisableVariable<const bool>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const bool>::checkEquality( uint8_t* mem )
-{
-  return *static_cast<uint8_t*>(mem) == *(uint8_t*)(&this->variable_);
-}
-
-// =========== char
-
-template <> uint32_t SynchronisableVariable<const char>::returnSize()
-{
-  return sizeof(uint8_t);
-}
-
-template <> void SynchronisableVariable<const char>::setAndIncrease( uint8_t*& mem )
-{
-  *(uint8_t*)(&this->variable_) = *static_cast<uint8_t*>(mem);
-  mem += SynchronisableVariable<const char>::returnSize();
-}
-
-template <> void SynchronisableVariable<const char>::getAndIncrease( uint8_t*& mem )
-{
-  *static_cast<uint8_t*>(mem) = *(uint8_t*)(&this->variable_);
-  mem += SynchronisableVariable<const char>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const char>::checkEquality( uint8_t* mem )
-{
-  return *static_cast<uint8_t*>(mem) == *(uint8_t*)(&this->variable_);
-}
-
-// =========== unsigned char
-
-template <> uint32_t SynchronisableVariable<const unsigned char>::returnSize()
-{
-  return sizeof(uint8_t);
-}
-
-template <> void SynchronisableVariable<const unsigned char>::setAndIncrease( uint8_t*& mem )
-{
-  *(uint8_t*)(&this->variable_) = *static_cast<uint8_t*>(mem);
-  mem += SynchronisableVariable<const unsigned char>::returnSize();
-}
-
-template <> void SynchronisableVariable<const unsigned char>::getAndIncrease( uint8_t*& mem )
-{
-  *static_cast<uint8_t*>(mem) = *(uint8_t*)(&this->variable_);
-  mem += SynchronisableVariable<const unsigned char>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const unsigned char>::checkEquality( uint8_t* mem )
-{
-  return *static_cast<uint8_t*>(mem) == *(uint8_t*)(&this->variable_);
-}
-
-// =========== short
-
-template <> uint32_t SynchronisableVariable<const short>::returnSize()
-{
-  return sizeof(int16_t);
-}
-
-template <> void SynchronisableVariable<const short>::setAndIncrease( uint8_t*& mem )
-{
-  *(short*)(&this->variable_) = *(int16_t*)(mem);
-  mem += SynchronisableVariable<const short>::returnSize();
-}
-
-template <> void SynchronisableVariable<const short>::getAndIncrease( uint8_t*& mem )
-{
-  *(int16_t*)(mem) = this->variable_;
-  mem += SynchronisableVariable<const short>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const short>::checkEquality( uint8_t* mem )
-{
-  return *(int16_t*)(mem) == static_cast<int16_t>(this->variable_);
-}
-
-// =========== unsigned short
-
-template <> uint32_t SynchronisableVariable<const unsigned short>::returnSize()
-{
-  return sizeof(uint16_t);
-}
-
-template <> void SynchronisableVariable<const unsigned short>::setAndIncrease( uint8_t*& mem )
-{
-  *(unsigned short*)(&this->variable_) = *(uint16_t*)(mem);
-  mem += SynchronisableVariable<const unsigned short>::returnSize();
-}
-
-template <> void SynchronisableVariable<const unsigned short>::getAndIncrease( uint8_t*& mem )
-{
-  *(uint16_t*)(mem) = this->variable_;
-  mem += SynchronisableVariable<const unsigned short>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const unsigned short>::checkEquality( uint8_t* mem )
-{
-  return *(uint16_t*)(mem) == this->variable_;
-}
-
-// =========== int
-
-template <> uint32_t SynchronisableVariable<const int>::returnSize()
-{
-  return sizeof(int32_t);
-}
-
-template <> void SynchronisableVariable<const int>::setAndIncrease( uint8_t*& mem )
-{
-  *(int *)(&this->variable_) = *(int32_t*)(mem);
-  mem += SynchronisableVariable<const int>::returnSize();
-}
-
-template <> void SynchronisableVariable<const int>::getAndIncrease( uint8_t*& mem )
-{
-  *(int32_t*)(mem) = this->variable_;
-  mem += SynchronisableVariable<const int>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const int>::checkEquality( uint8_t* mem )
-{
-  return *(int32_t*)(mem) == this->variable_;
-}
-
-// =========== unsigned int
-
-template <> uint32_t SynchronisableVariable<const unsigned int>::returnSize()
-{
-  return sizeof(uint32_t);
-}
-    
-template <> void SynchronisableVariable<const unsigned int>::setAndIncrease( uint8_t*& mem )
-{
-  *(unsigned int*)(&this->variable_) = *(uint32_t*)(mem);
-  mem += SynchronisableVariable<const unsigned int>::returnSize();
-}
-
-template <> void SynchronisableVariable<const unsigned int>::getAndIncrease( uint8_t*& mem )
-{
-  *(uint32_t*)(mem) = this->variable_;
-  mem += SynchronisableVariable<const unsigned int>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const unsigned int>::checkEquality( uint8_t* mem )
-{
-  return *(uint32_t*)(mem) == this->variable_;
-}
-
-// =========== long
-
-template <> uint32_t SynchronisableVariable<const long>::returnSize()
-{
-  return sizeof(int32_t);
-}
-
-template <> void SynchronisableVariable<const long>::setAndIncrease( uint8_t*& mem )
-{
-  *(long*)(&this->variable_) = *(int32_t*)(mem);
-  mem += SynchronisableVariable<const long>::returnSize();
-}
-
-template <> void SynchronisableVariable<const long>::getAndIncrease( uint8_t*& mem )
-{
-  *(int32_t*)(mem) = this->variable_;
-  mem += SynchronisableVariable<const long>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const long>::checkEquality( uint8_t* mem )
-{
-  return *(int32_t*)(mem) == this->variable_;
-}
-
-// =========== unsigned long
-
-template <> uint32_t SynchronisableVariable<const unsigned long>::returnSize()
-{
-  return sizeof(uint32_t);
-}
-
-template <> void SynchronisableVariable<const unsigned long>::setAndIncrease( uint8_t*& mem )
-{
-  *(unsigned long*)(&this->variable_) = *(uint32_t*)(mem);
-  mem += SynchronisableVariable<const unsigned long>::returnSize();
-}
-
-template <> void SynchronisableVariable<const unsigned long>::getAndIncrease( uint8_t*& mem )
-{
-  *(uint32_t*)(mem) = this->variable_;
-  mem += SynchronisableVariable<const unsigned long>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const unsigned long>::checkEquality( uint8_t* mem )
-{
-  return *(uint32_t*)(mem) == this->variable_;
-}
-
-// =========== long long
-
-template <> uint32_t SynchronisableVariable<const long long>::returnSize()
-{
-  return sizeof(int64_t);
-}
-
-template <> void SynchronisableVariable<const long long>::setAndIncrease( uint8_t*& mem )
-{
-  *(long long*)(&this->variable_) = *(int64_t*)(mem);
-  mem += SynchronisableVariable<const long long>::returnSize();
-}
-
-template <> void SynchronisableVariable<const long long>::getAndIncrease( uint8_t*& mem )
-{
-  *(int64_t*)(mem) = this->variable_;
-  mem += SynchronisableVariable<const long long>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const long long>::checkEquality( uint8_t* mem )
-{
-  return *(int64_t*)(mem) == this->variable_;
-}
-
-// =========== unsigned long long
-
-template <> uint32_t SynchronisableVariable<const unsigned long long>::returnSize()
-{
-  return sizeof(uint64_t);
-}
-
-template <> void SynchronisableVariable<const unsigned long long>::setAndIncrease( uint8_t*& mem )
-{
-  *(unsigned long long*)(&this->variable_) = *(uint64_t*)(mem);
-  mem += SynchronisableVariable<const unsigned long long>::returnSize();
-}
-
-template <> void SynchronisableVariable<const unsigned long long>::getAndIncrease( uint8_t*& mem )
-{
-  *(uint64_t*)(mem) = this->variable_;
-  mem += SynchronisableVariable<const unsigned long long>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const unsigned long long>::checkEquality( uint8_t* mem )
-{
-  return *(uint64_t*)(mem) == this->variable_;
-}
-
-// =========== float
-
-template <> uint32_t SynchronisableVariable<const float>::returnSize()
-{
-  return sizeof(uint32_t);
-}
-
-template <> void SynchronisableVariable<const float>::setAndIncrease( uint8_t*& mem )
-{
-  *(uint32_t*)(&this->variable_) = *(uint32_t*)(mem);
-  mem += SynchronisableVariable<const float>::returnSize();
-}
-
-template <> void SynchronisableVariable<const float>::getAndIncrease( uint8_t*& mem )
-{
-  *(uint32_t*)(mem) = *(uint32_t*)(&this->variable_);
-  mem += SynchronisableVariable<const float>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const float>::checkEquality( uint8_t* mem )
-{
-  return *(uint32_t*)(mem) == *(uint32_t*)(&this->variable_);
-}
-
-// =========== double
-
-template <> uint32_t SynchronisableVariable<const double>::returnSize()
-{
-  return sizeof(uint64_t);
-}
-
-template <> void SynchronisableVariable<const double>::setAndIncrease( uint8_t*& mem )
-{
-  *(uint64_t*)(&this->variable_) = *(uint64_t*)(mem);
-  mem += SynchronisableVariable<const double>::returnSize();
-}
-
-template <> void SynchronisableVariable<const double>::getAndIncrease( uint8_t*& mem )
-{
-  *(uint64_t*)(mem) = *(uint64_t*)(&this->variable_);
-  mem += SynchronisableVariable<const double>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const double>::checkEquality( uint8_t* mem )
-{
-  return *(uint64_t*)(mem) == *(uint64_t*)(&this->variable_);
-}
-
-// =========== long double
-
-template <> uint32_t SynchronisableVariable<const long double>::returnSize()
-{
-  return sizeof(uint64_t);
-}
-
-template <> void SynchronisableVariable<const long double>::setAndIncrease( uint8_t*& mem )
-{
-  double temp;
-  memcpy(&temp, mem, sizeof(uint64_t));
-  *(long double*)(&this->variable_) = static_cast<const long double>(temp);
-  mem += SynchronisableVariable<const long double>::returnSize();
-}
-
-template <> void SynchronisableVariable<const long double>::getAndIncrease( uint8_t*& mem )
-{
-  double temp = static_cast<double>(this->variable_);
-  memcpy(mem, &temp, sizeof(uint64_t));
-  mem += SynchronisableVariable<const long double>::returnSize();
-}
-
-template <> bool SynchronisableVariable<const long double>::checkEquality( uint8_t* mem )
-{
-  double temp = static_cast<double>(this->variable_);
-  return memcmp(&temp, mem, sizeof(uint64_t))==0;
-}
-
-// =========== string
-
-template <> uint32_t SynchronisableVariable<const std::string>::returnSize()
-{
-  return variable_.length()+1;
-}
-
-template <> void SynchronisableVariable<const std::string>::getAndIncrease( uint8_t*& mem )
-{
-  memcpy(mem, this->variable_.c_str(), this->variable_.length()+1);
-  mem += this->variable_.length()+1;
-}
-
-template <> void SynchronisableVariable<const std::string>::setAndIncrease( uint8_t*& mem )
-{
-  *(std::string*)(&this->variable_) = std::string((const char *)mem);
-  mem += this->variable_.length()+1;
-}
-
-template <> bool SynchronisableVariable<const std::string>::checkEquality( uint8_t* mem )
-{
-  return std::string((const char*)mem)==this->variable_;
-}
-
-// =========== Degree
-
-template <> uint32_t SynchronisableVariable<const Degree>::returnSize()
-{
-  return sizeof(Ogre::Real);
-}
-
-template <> void SynchronisableVariable<const Degree>::getAndIncrease( uint8_t*& mem )
-{
-  Ogre::Real r = this->variable_.valueDegrees();
-  memcpy(mem, &r, returnSize());
-  mem += returnSize();
-}
-
-template <> void SynchronisableVariable<const Degree>::setAndIncrease( uint8_t*& mem )
-{
-  Ogre::Real* r = (Ogre::Real*)mem;
-  (Degree&)this->variable_ = *r;
-  mem += returnSize();
-}
-
-template <> bool SynchronisableVariable<const Degree>::checkEquality( uint8_t* mem )
-{
-  Ogre::Real* r = (Ogre::Real*)mem;
-  return this->variable_==Degree(*r);
-}
-
-}
+} //namespace
Index: code/branches/netp3/src/network/synchronisable/SynchronisableVariable.h
===================================================================
--- code/branches/netp3/src/network/synchronisable/SynchronisableVariable.h	(revision 2989)
+++ code/branches/netp3/src/network/synchronisable/SynchronisableVariable.h	(revision 2990)
@@ -21,5 +21,5 @@
  *
  *   Author:
- *      Oliver Scheuss, (C) 2008
+ *      Oliver Scheuss
  *   Co-authors:
  *      ...
@@ -35,5 +35,7 @@
 #include <string>
 #include <cassert>
-#include "util/Math.h"
+#include "util/Serialise.h"
+#include "core/Core.h"
+#include "core/CoreIncludes.h"
 #include "network/synchronisable/NetworkCallback.h"
 #include "network/synchronisable/NetworkCallbackManager.h"
@@ -55,5 +57,5 @@
   {
     public:
-      virtual void getData(uint8_t*& mem, uint8_t mode)=0;
+      virtual uint32_t getData(uint8_t*& mem, uint8_t mode)=0;
       virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false)=0;
       virtual uint32_t getSize(uint8_t mode)=0;
@@ -74,13 +76,13 @@
 
       virtual inline uint8_t getMode(){ return mode_; }
-      virtual inline void getData(uint8_t*& mem, uint8_t mode);
+      virtual inline uint32_t getData(uint8_t*& mem, uint8_t mode);
       virtual inline void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
       virtual inline uint32_t getSize(uint8_t mode);
       virtual inline void* getReference(){ return (void *)&this->variable_; }
     protected:
-      bool checkEquality(uint8_t* mem);
-      void setAndIncrease(uint8_t*& mem);
-      void getAndIncrease(uint8_t*& mem);
-      uint32_t returnSize();
+//       inline bool checkEquality(uint8_t* mem);
+//       inline void loadAndIncrease(uint8_t*& mem);
+//       inline void saveAndIncrease(uint8_t*& mem);
+//       inline uint32_t returnSize();
       
       T& variable_;
@@ -97,7 +99,7 @@
       
       virtual inline uint8_t getMode(){ return 0x3; } //this basically is a hack ^^
-      virtual void getData(uint8_t*& mem, uint8_t mode);
+      virtual inline uint32_t getData(uint8_t*& mem, uint8_t mode);
       virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
-      virtual uint32_t getSize(uint8_t mode);
+      virtual inline uint32_t getSize(uint8_t mode);
     private:
       T varBuffer_;
@@ -119,8 +121,13 @@
   }
 
-  template <class T> void SynchronisableVariable<T>::getData(uint8_t*& mem, uint8_t mode)
+  template <class T> inline uint32_t SynchronisableVariable<T>::getData(uint8_t*& mem, uint8_t mode)
   {
     if ( state_ == this->mode_ )
-      getAndIncrease( mem );
+    {
+      saveAndIncrease( this->variable_, mem );
+      return returnSize( this->variable_ );
+    }
+    else
+      return 0;
 //   mem += SynchronisableVariable<T>::getSize();
   }
@@ -135,84 +142,82 @@
     if ( this->callback_ != 0 )
     {
-      if( forceCallback || !checkEquality( mem ) )
+      if( forceCallback || !checkEquality( this->variable_, mem ) )
         callback = true;
     }
   // write the data
-    setAndIncrease( mem );
-//   mem += SynchronisableVariable<T>::getSize();
+    loadAndIncrease( this->variable_, mem );
   // now do a callback if neccessary
     if ( callback )
       NetworkCallbackManager::triggerCallback( this->callback_ );
-      //this->callback_->call();
-  }
-
-  template <class T> uint32_t SynchronisableVariable<T>::getSize(uint8_t mode)
+  }
+
+  template <class T> inline uint32_t SynchronisableVariable<T>::getSize(uint8_t mode)
   {
     if ( mode == this->mode_ )
-      return returnSize();
+      return returnSize( this->variable_ );
     else
       return 0;
   }
 
-  template <> _NetworkExport uint32_t SynchronisableVariable<const bool>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const bool>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const bool>::getAndIncrease(uint8_t*& mem);
+  /*template <> _NetworkExport uint32_t SynchronisableVariable<const bool>::returnSize();
+  template <> _NetworkExport void     SynchronisableVariable<const bool>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const bool>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const bool>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned char>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const unsigned char>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const unsigned char>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned char>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned char>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const unsigned char>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const short>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const short>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const short>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const short>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const short>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const short>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned short>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const unsigned short>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const unsigned short>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned short>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned short>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const unsigned short>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const int>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const int>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const int>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const int>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const int>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const int>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned int>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const unsigned int>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const unsigned int>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned int>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned int>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const unsigned int>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const long>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const long>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const long>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const long>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const long>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const long>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned long>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const unsigned long>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const unsigned long>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned long>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned long>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const unsigned long>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const long long>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const long long>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const long long>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const long long>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const long long>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const long long>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const unsigned long long>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const unsigned long long>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const unsigned long long>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned long long>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const unsigned long long>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const unsigned long long>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const float>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const float>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const float>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const float>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const float>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const float>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const double>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const double>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const double>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const double>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const double>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const double>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const long double>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const long double>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const long double>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const long double>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const long double>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const long double>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const std::string>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const std::string>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const std::string>::getAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const std::string>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const std::string>::saveAndIncrease(uint8_t*& mem);
   template <> _NetworkExport bool     SynchronisableVariable<const std::string>::checkEquality(uint8_t* mem);
   template <> _NetworkExport uint32_t SynchronisableVariable<const Degree>::returnSize();
-  template <> _NetworkExport void     SynchronisableVariable<const Degree>::setAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport void     SynchronisableVariable<const Degree>::getAndIncrease(uint8_t*& mem);
-  template <> _NetworkExport bool     SynchronisableVariable<const Degree>::checkEquality(uint8_t* mem);
+  template <> _NetworkExport void     SynchronisableVariable<const Degree>::loadAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport void     SynchronisableVariable<const Degree>::saveAndIncrease(uint8_t*& mem);
+  template <> _NetworkExport bool     SynchronisableVariable<const Degree>::checkEquality(uint8_t* mem);*/
 
 
@@ -229,5 +234,5 @@
     }
 
-    template <class T> void SynchronisableVariableBidirectional<T>::getData(uint8_t*& mem, uint8_t mode)
+    template <class T> uint32_t SynchronisableVariableBidirectional<T>::getData(uint8_t*& mem, uint8_t mode)
     {
       if ( this->mode_ == mode )
@@ -243,6 +248,7 @@
       mem += sizeof(this->varReference_);
   // now write the content
-      SynchronisableVariable<T>::getAndIncrease( mem );
+      saveAndIncrease( this->variable_, mem );
 //   mem += SynchronisableVariable<T>::getSize();
+      return SynchronisableVariableBidirectional::getSize(mode);
     }
 
@@ -260,12 +266,12 @@
         else{
           // apply data
-          mem += sizeof(varReference_);
-          if ( SynchronisableVariableBidirectional<T>::checkEquality( mem )==true )
+          if ( checkEquality( this->variable_, mem+sizeof(varReference_) )==true )
           {
-            mem += SynchronisableVariable<T>::getSize( mode );
+            mem += getSize( mode );
             return;
           }
           else
           {
+            mem += sizeof(varReference_);
             memcpy((void*)&this->varBuffer_, &this->variable_, sizeof(T));
             if ( this->callback_ != 0 )
@@ -285,5 +291,5 @@
           this->varReference_ = *static_cast<uint8_t*>(mem);
           mem += sizeof(varReference_);
-          if ( SynchronisableVariable<T>::checkEquality( mem ) == false )
+          if ( checkEquality( this->variable_, mem ) == false )
           {
             // value changed so remark for callback
@@ -294,5 +300,5 @@
       }
   // now write the data
-      SynchronisableVariable<T>::setAndIncrease(mem);
+      loadAndIncrease(this->variable_, mem);
   // now do a callback if neccessary
       if ( callback )
@@ -301,7 +307,7 @@
     }
 
-    template <class T> uint32_t SynchronisableVariableBidirectional<T>::getSize(uint8_t mode)
-    {
-      return SynchronisableVariable<T>::returnSize() + sizeof(varReference_);
+    template <class T> inline uint32_t SynchronisableVariableBidirectional<T>::getSize(uint8_t mode)
+    {
+      return returnSize( this->variable_ ) + sizeof(varReference_);
     }
   
@@ -309,4 +315,5 @@
 }
 
+//#include "network/synchronisable/SynchronisableVariableSpecialisations.h"
 
 #endif
Index: code/branches/netp3/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- code/branches/netp3/src/orxonox/OrxonoxPrereqs.h	(revision 2989)
+++ code/branches/netp3/src/orxonox/OrxonoxPrereqs.h	(revision 2990)
@@ -158,4 +158,5 @@
     class SpawnPoint;
     class TeamSpawnPoint;
+    class Test;
 
     class Spectator;
Index: code/branches/netp3/src/orxonox/objects/Test.cc
===================================================================
--- code/branches/netp3/src/orxonox/objects/Test.cc	(revision 2989)
+++ code/branches/netp3/src/orxonox/objects/Test.cc	(revision 2990)
@@ -31,5 +31,7 @@
 #include "core/ConfigValueIncludes.h"
 #include "core/ConsoleCommand.h"
+#include "network/NetworkFunction.h"
 #include "Test.h"
+#include "util/MultiType.h"
 
 namespace orxonox
@@ -41,4 +43,15 @@
   SetConsoleCommand(Test, printV3, true).accessLevel(AccessLevel::User);
   SetConsoleCommand(Test, printV4, true).accessLevel(AccessLevel::User);
+  SetConsoleCommand(Test, call, true).accessLevel(AccessLevel::User);
+  SetConsoleCommand(Test, call2, true).accessLevel(AccessLevel::User);
+  
+  
+  //void=* aaaaa = copyPtr<sizeof(&Test::printV1)>( &NETWORK_FUNCTION_POINTER, &Test::printV1 );
+  //void* NETWORK_FUNCTION_TEST_B = memcpy(&NETWORK_FUNCTION_POINTER, &a, sizeof(a));
+//   NetworkFunctionBase* NETWORK_FUNCTION_TEST_C = new NetworkFunctionStatic( createFunctor(&Test::printV1), "bla", NETWORK_FUNCTION_POINTER );
+  
+  registerStaticNetworkFunction( &Test::printV1 );
+  registerMemberNetworkFunction( Test, checkU1 );
+  registerMemberNetworkFunction( Test, printBlaBla );
   
   Test* Test::instance_ = 0;
@@ -73,9 +86,9 @@
 
 
-	void Test::registerVariables()
-	{
-		registerVariable ( u1, variableDirection::toclient, new NetworkCallback<Test> ( this, &Test::checkU1 ));
+  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, variableDirection::serverMaster, new NetworkCallback<Test> ( this, &Test::checkU3 ), true );
+    registerVariable ( u3, variableDirection::serverMaster, new NetworkCallback<Test> ( this, &Test::checkU3 ), true );
     registerVariable ( u4, variableDirection::clientMaster, new NetworkCallback<Test> ( this, &Test::checkU4 ), true );
     
@@ -84,6 +97,41 @@
     registerVariable ( s3, variableDirection::serverMaster, new NetworkCallback<Test> ( this, &Test::checkS3 ), true );
     registerVariable ( s4, variableDirection::clientMaster, new NetworkCallback<Test> ( this, &Test::checkS4 ), true );
-	}
-
+  }
+  
+  void Test::call(unsigned int clientID)
+  {
+    callStaticNetworkFunction( &Test::printV1, clientID );
+    callStaticNetworkFunction( &Test::printV1, clientID );
+  }
+  
+  void Test::call2(unsigned int clientID, std::string s1, std::string s2, std::string s3, std::string s4)
+  {
+    callMemberNetworkFunction( Test, printBlaBla, this->getObjectID(), clientID, s1, s2, s3, s4, s4 );
+  }
+  
+  void Test::tick(float dt)
+  {
+//     std::string str1 = "blub";
+//     //MultiType mt1(std::string("blub"));
+//     MultiType mt1(str1);
+//     uint8_t* mem = new uint8_t[mt1.getNetworkSize()];
+//     uint8_t* temp = mem;
+//     mt1.exportData( temp );
+//     assert( temp-mem == mt1.getNetworkSize() );
+//     MultiType mt2;
+//     temp = mem;
+//     mt2.importData( temp );
+//     assert( temp-mem == mt1.getNetworkSize() );
+//     COUT(0) << mt2 << endl;
+    if(!Core::isMaster())
+      call2(0, "bal", "a", "n", "ce");
+//       callMemberNetworkFunction( Test, checkU1, this->getObjectID(), 0 );
+  }
+  
+  void Test::printBlaBla(std::string s1, std::string s2, std::string s3, std::string s4, std::string s5)
+  {
+    COUT(0) << s1 << s2 << s3 << s4 << s5 << endl;
+  }
+  
   void Test::checkU1(){ COUT(1) << "U1 changed: " << u1 << std::endl; }
   void Test::checkU2(){ COUT(1) << "U2 changed: " << u2 << std::endl; }
Index: code/branches/netp3/src/orxonox/objects/Test.h
===================================================================
--- code/branches/netp3/src/orxonox/objects/Test.h	(revision 2989)
+++ code/branches/netp3/src/orxonox/objects/Test.h	(revision 2990)
@@ -33,4 +33,5 @@
 #include "core/BaseObject.h"
 #include "network/synchronisable/Synchronisable.h"
+#include "Tickable.h"
 
 
@@ -41,5 +42,5 @@
 namespace orxonox
 {
-  class _OrxonoxExport Test: public BaseObject, public Synchronisable
+  class _OrxonoxExport Test: public BaseObject, public Synchronisable, public Tickable
   {
     public:
@@ -49,4 +50,8 @@
       void setConfigValues();
       void registerVariables();
+      
+      static void call(unsigned int clientID);
+      void call2(unsigned int clientID, std::string s1, std::string s2, std::string s3, std::string s4);
+      virtual void tick(float dt);
 
 
@@ -75,4 +80,6 @@
       static void printV3(){ instance_->checkU3(); }
       static void printV4(){ instance_->checkU4(); }
+      
+      void printBlaBla(std::string s1, std::string s2, std::string s3, std::string s4, std::string s5);
 
     private:
Index: code/branches/netp3/src/orxonox/objects/controllers/AIController.cc
===================================================================
--- code/branches/netp3/src/orxonox/objects/controllers/AIController.cc	(revision 2989)
+++ code/branches/netp3/src/orxonox/objects/controllers/AIController.cc	(revision 2990)
@@ -101,15 +101,18 @@
     void AIController::tick(float dt)
     {
-        if (!this->isActive())
-            return;
-
-        if (this->target_)
-            this->aimAtTarget();
-
-        if (this->bHasTargetPosition_)
-            this->moveToTargetPosition(dt);
-
-        if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(500) && this->isLookingAtTarget(Ogre::Math::PI / 20.0))
-            this->getControllableEntity()->fire(WeaponMode::fire);
+        if(Core::isMaster())
+        {
+            if (!this->isActive())
+                return;
+    
+            if (this->target_)
+                this->aimAtTarget();
+    
+            if (this->bHasTargetPosition_)
+                this->moveToTargetPosition(dt);
+    
+            if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(500) && this->isLookingAtTarget(Ogre::Math::PI / 20.0))
+                this->getControllableEntity()->fire(WeaponMode::fire);
+        }
 
         SUPER(AIController, tick, dt);
Index: code/branches/netp3/src/orxonox/objects/worldentities/ControllableEntity.cc
===================================================================
--- code/branches/netp3/src/orxonox/objects/worldentities/ControllableEntity.cc	(revision 2989)
+++ code/branches/netp3/src/orxonox/objects/worldentities/ControllableEntity.cc	(revision 2990)
@@ -66,12 +66,12 @@
         this->mouseLookSpeed_ = 200;
 
-        this->server_position_         = Vector3::ZERO;
-        this->client_position_         = Vector3::ZERO;
-        this->server_linear_velocity_  = Vector3::ZERO;
-        this->client_linear_velocity_  = Vector3::ZERO;
-        this->server_orientation_      = Quaternion::IDENTITY;
-        this->client_orientation_      = Quaternion::IDENTITY;
-        this->server_angular_velocity_ = Vector3::ZERO;
-        this->client_angular_velocity_ = Vector3::ZERO;
+        this->common_position_         = Vector3::ZERO;
+//         this->client_position_         = Vector3::ZERO;
+        this->common_linear_velocity_  = Vector3::ZERO;
+//         this->client_linear_velocity_  = Vector3::ZERO;
+        this->common_orientation_      = Quaternion::IDENTITY;
+//         this->client_orientation_      = Quaternion::IDENTITY;
+        this->common_angular_velocity_ = Vector3::ZERO;
+//         this->client_angular_velocity_ = Vector3::ZERO;
 
 
@@ -326,18 +326,18 @@
             if (!this->isDynamic())
             {
-                if (GameMode::isMaster())
-                {
-                    this->server_position_ = this->getPosition();
-                    this->server_orientation_ = this->getOrientation();
-                    this->server_linear_velocity_ = this->getVelocity();
-                    this->server_angular_velocity_ = this->getAngularVelocity();
-                }
-                else if (this->bHasLocalController_)
-                {
-                    this->client_position_ = this->getPosition();
-                    this->client_orientation_ = this->getOrientation();
-                    this->client_linear_velocity_ = this->getVelocity();
-                    this->client_angular_velocity_ = this->getAngularVelocity();
-                }
+//                 if (GameMode::isMaster())
+//                 {
+                    this->common_position_ = this->getPosition();
+                    this->common_orientation_ = this->getOrientation();
+                    this->common_linear_velocity_ = this->getVelocity();
+                    this->common_angular_velocity_ = this->getAngularVelocity();
+//                 }
+//                 else if (this->bHasLocalController_)
+//                 {
+//                     this->client_position_ = this->getPosition();
+//                     this->client_orientation_ = this->getOrientation();
+//                     this->client_linear_velocity_ = this->getVelocity();
+//                     this->client_angular_velocity_ = this->getAngularVelocity();
+//                 }
             }
         }
@@ -349,16 +349,21 @@
         registerVariable(this->hudtemplate_,             variableDirection::toclient);
 
-        registerVariable(this->server_position_,         variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
-        registerVariable(this->server_linear_velocity_,  variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerLinearVelocity));
-        registerVariable(this->server_orientation_,      variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
-        registerVariable(this->server_angular_velocity_, variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerAngularVelocity));
-
-        registerVariable(this->server_overwrite_,        variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
-        registerVariable(this->client_overwrite_,        variableDirection::toserver);
-
-        registerVariable(this->client_position_,         variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
-        registerVariable(this->client_linear_velocity_,  variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientLinearVelocity));
-        registerVariable(this->client_orientation_,      variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
-        registerVariable(this->client_angular_velocity_, variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientAngularVelocity));
+//         registerVariable(this->server_position_,         variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
+//         registerVariable(this->server_linear_velocity_,  variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerLinearVelocity));
+//         registerVariable(this->server_orientation_,      variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
+//         registerVariable(this->server_angular_velocity_, variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerAngularVelocity));
+// 
+//         registerVariable(this->server_overwrite_,        variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
+//         registerVariable(this->client_overwrite_,        variableDirection::toserver);
+// 
+//         registerVariable(this->client_position_,         variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
+//         registerVariable(this->client_linear_velocity_,  variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientLinearVelocity));
+//         registerVariable(this->client_orientation_,      variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
+//         registerVariable(this->client_angular_velocity_, variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientAngularVelocity));
+        
+        registerVariable(this->common_position_,         variableDirection::serverMaster, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition), true);
+        registerVariable(this->common_linear_velocity_,  variableDirection::serverMaster, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerLinearVelocity), true);
+        registerVariable(this->common_orientation_,      variableDirection::serverMaster, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation), true);
+        registerVariable(this->common_angular_velocity_, variableDirection::serverMaster, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerAngularVelocity), true);
 
         registerVariable(this->playerID_,                variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));
@@ -368,5 +373,5 @@
     {
         if (!this->bHasLocalController_)
-            MobileEntity::setPosition(this->server_position_);
+            MobileEntity::setPosition(this->common_position_);
     }
 
@@ -374,5 +379,5 @@
     {
         if (!this->bHasLocalController_)
-            MobileEntity::setVelocity(this->server_linear_velocity_);
+            MobileEntity::setVelocity(this->common_linear_velocity_);
     }
 
@@ -380,5 +385,5 @@
     {
         if (!this->bHasLocalController_)
-            MobileEntity::setOrientation(this->server_orientation_);
+            MobileEntity::setOrientation(this->common_orientation_);
     }
 
@@ -386,5 +391,5 @@
     {
         if (!this->bHasLocalController_)
-            MobileEntity::setAngularVelocity(this->server_angular_velocity_);
+            MobileEntity::setAngularVelocity(this->common_angular_velocity_);
     }
 
@@ -393,10 +398,10 @@
         if (this->bHasLocalController_)
         {
-            this->setPosition(this->server_position_);
-            this->setOrientation(this->server_orientation_);
-            this->setVelocity(this->server_linear_velocity_);
-            this->setAngularVelocity(this->server_angular_velocity_);
-
-            this->client_overwrite_ = this->server_overwrite_;
+//             this->setPosition(this->server_position_);
+//             this->setOrientation(this->server_orientation_);
+//             this->setVelocity(this->server_linear_velocity_);
+//             this->setAngularVelocity(this->server_angular_velocity_);
+
+//             this->client_overwrite_ = this->server_overwrite_;
         }
     }
@@ -406,6 +411,6 @@
         if (this->server_overwrite_ == this->client_overwrite_)
         {
-            MobileEntity::setPosition(this->client_position_);
-            this->server_position_ = this->getPosition();
+//             MobileEntity::setPosition(this->client_position_);
+//             this->server_position_ = this->getPosition();
         }
     }
@@ -415,6 +420,6 @@
         if (this->server_overwrite_ == this->client_overwrite_)
         {
-            MobileEntity::setVelocity(this->client_linear_velocity_);
-            this->server_linear_velocity_ = this->getVelocity();
+//             MobileEntity::setVelocity(this->client_linear_velocity_);
+//             this->server_linear_velocity_ = this->getVelocity();
         }
     }
@@ -424,6 +429,6 @@
         if (this->server_overwrite_ == this->client_overwrite_)
         {
-            MobileEntity::setOrientation(this->client_orientation_);
-            this->server_orientation_ = this->getOrientation();
+//             MobileEntity::setOrientation(this->client_orientation_);
+//             this->server_orientation_ = this->getOrientation();
         }
     }
@@ -433,6 +438,6 @@
         if (this->server_overwrite_ == this->client_overwrite_)
         {
-            MobileEntity::setAngularVelocity(this->client_angular_velocity_);
-            this->server_angular_velocity_ = this->getAngularVelocity();
+//             MobileEntity::setAngularVelocity(this->client_angular_velocity_);
+//             this->server_angular_velocity_ = this->getAngularVelocity();
         }
     }
@@ -440,60 +445,60 @@
     void ControllableEntity::setPosition(const Vector3& position)
     {
-        if (GameMode::isMaster())
-        {
+//         if (GameMode::isMaster())
+//         {
             MobileEntity::setPosition(position);
-            this->server_position_ = this->getPosition();
-            ++this->server_overwrite_;
-        }
-        else if (this->bHasLocalController_)
-        {
-            MobileEntity::setPosition(position);
-            this->client_position_ = this->getPosition();
-        }
+            this->common_position_ = this->getPosition();
+//             ++this->server_overwrite_;
+//         }
+//         else if (this->bHasLocalController_)
+//         {
+//             MobileEntity::setPosition(position);
+//             this->client_position_ = this->getPosition();
+//         }
     }
 
     void ControllableEntity::setOrientation(const Quaternion& orientation)
     {
-        if (GameMode::isMaster())
-        {
+//         if (GameMode::isMaster())
+//         {
             MobileEntity::setOrientation(orientation);
-            this->server_orientation_ = this->getOrientation();
-            ++this->server_overwrite_;
-        }
-        else if (this->bHasLocalController_)
-        {
-            MobileEntity::setOrientation(orientation);
-            this->client_orientation_ = this->getOrientation();
-        }
+            this->common_orientation_ = this->getOrientation();
+//             ++this->server_overwrite_;
+//         }
+//         else if (this->bHasLocalController_)
+//         {
+//             MobileEntity::setOrientation(orientation);
+//             this->client_orientation_ = this->getOrientation();
+//         }
     }
 
     void ControllableEntity::setVelocity(const Vector3& velocity)
     {
-        if (GameMode::isMaster())
-        {
+//         if (GameMode::isMaster())
+//         {
             MobileEntity::setVelocity(velocity);
-            this->server_linear_velocity_ = this->getVelocity();
-            ++this->server_overwrite_;
-        }
-        else if (this->bHasLocalController_)
-        {
-            MobileEntity::setVelocity(velocity);
-            this->client_linear_velocity_ = this->getVelocity();
-        }
+            this->common_linear_velocity_ = this->getVelocity();
+//             ++this->server_overwrite_;
+//         }
+//         else if (this->bHasLocalController_)
+//         {
+//             MobileEntity::setVelocity(velocity);
+//             this->client_linear_velocity_ = this->getVelocity();
+//         }
     }
 
     void ControllableEntity::setAngularVelocity(const Vector3& velocity)
     {
-        if (GameMode::isMaster())
-        {
+//         if (GameMode::isMaster())
+//         {
             MobileEntity::setAngularVelocity(velocity);
-            this->server_angular_velocity_ = this->getAngularVelocity();
-            ++this->server_overwrite_;
-        }
-        else if (this->bHasLocalController_)
-        {
-            MobileEntity::setAngularVelocity(velocity);
-            this->client_angular_velocity_ = this->getAngularVelocity();
-        }
+            this->common_angular_velocity_ = this->getAngularVelocity();
+//             ++this->server_overwrite_;
+//         }
+//         else if (this->bHasLocalController_)
+//         {
+//             MobileEntity::setAngularVelocity(velocity);
+//             this->client_angular_velocity_ = this->getAngularVelocity();
+//         }
     }
 
@@ -501,18 +506,18 @@
     {
         MobileEntity::setWorldTransform(worldTrans);
-        if (GameMode::isMaster())
-        {
-            this->server_position_ = this->getPosition();
-            this->server_orientation_ = this->getOrientation();
-            this->server_linear_velocity_ = this->getVelocity();
-            this->server_angular_velocity_ = this->getAngularVelocity();
-        }
-        else if (this->bHasLocalController_)
-        {
-            this->client_position_ = this->getPosition();
-            this->client_orientation_ = this->getOrientation();
-            this->client_linear_velocity_ = this->getVelocity();
-            this->client_angular_velocity_ = this->getAngularVelocity();
-        }
+//         if (GameMode::isMaster())
+//         {
+            this->common_position_ = this->getPosition();
+            this->common_orientation_ = this->getOrientation();
+            this->common_linear_velocity_ = this->getVelocity();
+            this->common_angular_velocity_ = this->getAngularVelocity();
+//         }
+//         else if (this->bHasLocalController_)
+//         {
+//             this->client_position_ = this->getPosition();
+//             this->client_orientation_ = this->getOrientation();
+//             this->client_linear_velocity_ = this->getVelocity();
+//             this->client_angular_velocity_ = this->getAngularVelocity();
+//         }
     }
 }
Index: code/branches/netp3/src/orxonox/objects/worldentities/ControllableEntity.h
===================================================================
--- code/branches/netp3/src/orxonox/objects/worldentities/ControllableEntity.h	(revision 2989)
+++ code/branches/netp3/src/orxonox/objects/worldentities/ControllableEntity.h	(revision 2990)
@@ -164,12 +164,16 @@
             bool bDestroyWhenPlayerLeft_;
 
-            Vector3 server_position_;
-            Vector3 client_position_;
-            Vector3 server_linear_velocity_;
-            Vector3 client_linear_velocity_;
-            Quaternion server_orientation_;
-            Quaternion client_orientation_;
-            Vector3 server_angular_velocity_;
-            Vector3 client_angular_velocity_;
+//             Vector3 server_position_;
+            Vector3 common_position_;
+//             Vector3 client_position_;
+//             Vector3 server_linear_velocity_;
+//             Vector3 client_linear_velocity_;
+            Vector3 common_linear_velocity_;
+//             Quaternion server_orientation_;
+//             Quaternion client_orientation_;
+            Quaternion common_orientation_;
+//             Vector3 server_angular_velocity_;
+//             Vector3 client_angular_velocity_;
+            Vector3 common_angular_velocity_;
 
             PlayerInfo* player_;
Index: code/branches/netp3/src/orxonox/objects/worldentities/MobileEntity.h
===================================================================
--- code/branches/netp3/src/orxonox/objects/worldentities/MobileEntity.h	(revision 2989)
+++ code/branches/netp3/src/orxonox/objects/worldentities/MobileEntity.h	(revision 2990)
@@ -61,5 +61,5 @@
                 { this->setAngularVelocity(Vector3(x, y, z)); }
             inline const Vector3& getAngularVelocity() const
-                { return this->linearAcceleration_; }
+                { return this->angularVelocity_; }
 
             void setAcceleration(const Vector3& acceleration);
Index: code/branches/netp3/src/orxonox/objects/worldentities/pawns/Pawn.cc
===================================================================
--- code/branches/netp3/src/orxonox/objects/worldentities/pawns/Pawn.cc	(revision 2989)
+++ code/branches/netp3/src/orxonox/objects/worldentities/pawns/Pawn.cc	(revision 2990)
@@ -39,8 +39,11 @@
 #include "objects/worldentities/ParticleSpawner.h"
 #include "objects/worldentities/ExplosionChunk.h"
+#include "network/NetworkFunction.h"
 
 namespace orxonox
 {
     CreateFactory(Pawn);
+    
+    registerMemberNetworkFunction( Pawn, doFire );
 
     Pawn::Pawn(BaseObject* creator) : ControllableEntity(creator)
@@ -117,17 +120,18 @@
         SUPER(Pawn, tick, dt);
 
-        if (this->weaponSystem_)
-        {
-            if (this->fire_ & WeaponMode::fire)
-                this->weaponSystem_->fire(WeaponMode::fire);
-            if (this->fire_ & WeaponMode::altFire)
-                this->weaponSystem_->fire(WeaponMode::altFire);
-            if (this->fire_ & WeaponMode::altFire2)
-                this->weaponSystem_->fire(WeaponMode::altFire2);
-        }
-        this->fire_ = this->firehack_;
-        this->firehack_ = 0x0;
-
-        if (this->health_ <= 0)
+//         if (this->weaponSystem_)
+//         {
+//             if (this->fire_ & WeaponMode::fire)
+//                 this->weaponSystem_->fire(WeaponMode::fire);
+//             if (this->fire_ & WeaponMode::altFire)
+//                 this->weaponSystem_->fire(WeaponMode::altFire);
+//             if (this->fire_ & WeaponMode::altFire2)
+//                 this->weaponSystem_->fire(WeaponMode::altFire2);
+//         }
+//         this->fire_ = this->firehack_;
+//         this->firehack_ = 0x0;
+
+        if (Core::isMaster())
+          if (this->health_ <= 0)
             this->death();
     }
@@ -254,5 +258,20 @@
     void Pawn::fire(WeaponMode::Enum fireMode)
     {
-        this->firehack_ |= fireMode;
+        doFire(fireMode);
+    }
+    
+    void Pawn::doFire(uint8_t fireMode)
+    {
+        if(Core::isMaster())
+        {
+            if (this->weaponSystem_)
+                this->weaponSystem_->fire((WeaponMode::Enum)fireMode);
+        }
+        else
+        {
+            callMemberNetworkFunction( Pawn, doFire, this->getObjectID(), 0, ((uint8_t)fireMode));
+            if (this->weaponSystem_)
+                this->weaponSystem_->fire((WeaponMode::Enum)fireMode);
+        }
     }
 
Index: code/branches/netp3/src/orxonox/objects/worldentities/pawns/Pawn.h
===================================================================
--- code/branches/netp3/src/orxonox/objects/worldentities/pawns/Pawn.h	(revision 2989)
+++ code/branches/netp3/src/orxonox/objects/worldentities/pawns/Pawn.h	(revision 2990)
@@ -80,4 +80,5 @@
 
             virtual void fire(WeaponMode::Enum fireMode);
+            virtual void doFire(uint8_t fireMode);
             virtual void postSpawn();
 
Index: code/branches/netp3/src/util/MultiType.h
===================================================================
--- code/branches/netp3/src/util/MultiType.h	(revision 2989)
+++ code/branches/netp3/src/util/MultiType.h	(revision 2990)
@@ -80,28 +80,28 @@
     enum MT_Type
     {
-        MT_null,
-        MT_char,
-        MT_uchar,
-        MT_short,
-        MT_ushort,
-        MT_int,
-        MT_uint,
-        MT_long,
-        MT_ulong,
-        MT_longlong,
-        MT_ulonglong,
-        MT_float,
-        MT_double,
-        MT_longdouble,
-        MT_bool,
-        MT_void,
-        MT_string,
-        MT_vector2,
-        MT_vector3,
-        MT_vector4,
-        MT_colourvalue,
-        MT_quaternion,
-        MT_radian,
-        MT_degree
+        MT_null=0,
+        MT_char=1,
+        MT_uchar=2,
+        MT_short=3,
+        MT_ushort=4,
+        MT_int=5,
+        MT_uint=6,
+        MT_long=7,
+        MT_ulong=8,
+        MT_longlong=9,
+        MT_ulonglong=10,
+        MT_float=11,
+        MT_double=12,
+        MT_longdouble=13,
+        MT_bool=14,
+        MT_void=15,
+        MT_string=16,
+        MT_vector2=17,
+        MT_vector3=18,
+        MT_vector4=19,
+        MT_colourvalue=20,
+        MT_quaternion=21,
+        MT_radian=22,
+        MT_degree=23
     };
 
@@ -223,4 +223,8 @@
 
             virtual void toString(std::ostream& outstream) const = 0;
+            
+            virtual void importData( uint8_t*& mem )=0;
+            virtual void exportData( uint8_t*& mem ) const=0;
+            virtual uint8_t getSize() const=0;
 
             MT_Type type_;          //!< The type of the current value
@@ -320,4 +324,14 @@
             template <typename T> inline bool isType()                  const { return false; } // Only works for specialized values - see below
             std::string                       getTypename()             const;
+            
+            /** @brief Saves the value of the MT to a bytestream (pointed at by mem) and increases mem pointer by size of MT */
+            inline void                       exportData(uint8_t*& mem) const { assert(sizeof(MT_Type)<=8); *(uint8_t*)(mem) = this->getType(); mem+=sizeof(uint8_t); this->value_->exportData(mem); }
+            /** @brief Loads the value of the MT from a bytestream (pointed at by mem) and increases mem pointer by size of MT */
+            inline void                       importData(uint8_t*& mem) { assert(sizeof(MT_Type)<=8); this->setType(static_cast<MT_Type>(*(uint8_t*)mem)); mem+=sizeof(uint8_t); this->value_->importData(mem); }
+            /** @brief Saves the value of the MT to a bytestream and increases pointer to bytestream by size of MT */
+            inline uint8_t*&                  operator << (uint8_t*& mem) { importData(mem); return mem; }
+            /** @brief Loads the value of the MT to a bytestream and increases pointer to bytestream by size of MT */
+            inline void                       operator >> (uint8_t*& mem) const { exportData(mem); }
+            inline uint32_t                   getNetworkSize() const { assert(this->value_); return this->value_->getSize() + sizeof(uint8_t); }
 
             /** @brief Checks whether the value is a default one. */
Index: code/branches/netp3/src/util/MultiTypeValue.h
===================================================================
--- code/branches/netp3/src/util/MultiTypeValue.h	(revision 2989)
+++ code/branches/netp3/src/util/MultiTypeValue.h	(revision 2990)
@@ -40,4 +40,6 @@
 #include "MathConvert.h"
 #include "MultiType.h"
+#include "Serialise.h"
+#include <cassert>
 
 namespace orxonox
@@ -147,7 +149,116 @@
         /** @brief Puts the current value on the stream */
         inline void toString(std::ostream& outstream) const { outstream << this->value_; }
+        
+        /** @brief loads data from the bytestream (mem) into the MT and increases the bytestream pointer by the size of the data */
+        inline void importData( uint8_t*& mem )         { loadAndIncrease( /*(const T&)*/this->value_, mem ); }
+        /** @brief saves data from the MT into the bytestream (mem) and increases the bytestream pointer by the size of the data */
+        inline void exportData( uint8_t*& mem ) const   { saveAndIncrease( /*(const T&)*/this->value_, mem ); }
+        /** @brief returns the size of the data that would be saved by exportData */
+        inline uint8_t getSize() const { return returnSize( this->value_ ); }
 
         T value_; //!< The stored value
     };
+    
+    // Import / Export specialisation
+    // ColourValue
+    template <> inline void MT_Value<ColourValue>::importData( uint8_t*& mem )
+    {
+        loadAndIncrease( this->value_.r, mem );
+        loadAndIncrease( this->value_.g, mem );
+        loadAndIncrease( this->value_.b, mem );
+        loadAndIncrease( this->value_.a, mem );
+    }
+    template <> inline void MT_Value<ColourValue>::exportData( uint8_t*& mem ) const
+    {
+        saveAndIncrease( this->value_.r, mem );
+        saveAndIncrease( this->value_.g, mem );
+        saveAndIncrease( this->value_.b, mem );
+        saveAndIncrease( this->value_.a, mem );
+    }
+    template <> inline uint8_t MT_Value<ColourValue>::getSize() const
+    {
+        return 4*returnSize(this->value_.r);
+    }
+    // Ogre::Quaternion
+    template <> inline void MT_Value<Ogre::Quaternion>::importData( uint8_t*& mem )
+    {
+        loadAndIncrease( this->value_.x, mem );
+        loadAndIncrease( this->value_.y, mem );
+        loadAndIncrease( this->value_.z, mem );
+        loadAndIncrease( this->value_.w, mem );
+    }
+    template <> inline void MT_Value<Ogre::Quaternion>::exportData( uint8_t*& mem ) const
+    {
+        saveAndIncrease( this->value_.x, mem );
+        saveAndIncrease( this->value_.y, mem );
+        saveAndIncrease( this->value_.z, mem );
+        saveAndIncrease( this->value_.w, mem );
+    }template <> inline uint8_t MT_Value<Ogre::Quaternion>::getSize() const
+    {
+        return 4*returnSize(this->value_.x);
+    }
+    // Ogre::Vector2
+    template <> inline void MT_Value<Ogre::Vector2>::importData( uint8_t*& mem )
+    {
+        loadAndIncrease( this->value_.x, mem );
+        loadAndIncrease( this->value_.y, mem );
+    }
+    template <> inline void MT_Value<Ogre::Vector2>::exportData( uint8_t*& mem ) const
+    {
+        saveAndIncrease( this->value_.x, mem );
+        saveAndIncrease( this->value_.y, mem );
+    }
+    template <> inline uint8_t MT_Value<Ogre::Vector2>::getSize() const
+    {
+        return 2*returnSize(this->value_.x);
+    }
+    // Ogre::Vector3
+    template <> inline void MT_Value<Ogre::Vector3>::importData( uint8_t*& mem )
+    {
+        loadAndIncrease( this->value_.x, mem );
+        loadAndIncrease( this->value_.y, mem );
+        loadAndIncrease( this->value_.z, mem );
+    }
+    template <> inline void MT_Value<Ogre::Vector3>::exportData( uint8_t*& mem ) const
+    {
+        saveAndIncrease( this->value_.x, mem );
+        saveAndIncrease( this->value_.y, mem );
+        saveAndIncrease( this->value_.z, mem );
+    }
+    template <> inline uint8_t MT_Value<Ogre::Vector3>::getSize() const
+    {
+        return 3*returnSize(this->value_.x);
+    }
+    // Ogre::Vector4
+    template <> inline void MT_Value<Ogre::Vector4>::importData( uint8_t*& mem )
+    {
+        loadAndIncrease( this->value_.x, mem );
+        loadAndIncrease( this->value_.y, mem );
+        loadAndIncrease( this->value_.z, mem );
+        loadAndIncrease( this->value_.w, mem );
+    }
+    template <> inline void MT_Value<Ogre::Vector4>::exportData( uint8_t*& mem ) const
+    {
+        saveAndIncrease( this->value_.x, mem );
+        saveAndIncrease( this->value_.y, mem );
+        saveAndIncrease( this->value_.z, mem );
+        saveAndIncrease( this->value_.w, mem );
+    }
+    template <> inline uint8_t MT_Value<Ogre::Vector4>::getSize() const
+    {
+        return 4*returnSize(this->value_.x);
+    }
+    template <> inline void MT_Value<void*>::importData( uint8_t*& mem )
+    {
+        assert(0);
+    }
+    template <> inline void MT_Value<void*>::exportData( uint8_t*& mem ) const
+    {
+        assert(0);
+    }
+    template <> inline uint8_t MT_Value<void*>::getSize() const
+    {
+        assert(0); return 0;
+    }
 }
 
Index: code/branches/netp3/src/util/Serialise.h
===================================================================
--- code/branches/netp3/src/util/Serialise.h	(revision 2990)
+++ code/branches/netp3/src/util/Serialise.h	(revision 2990)
@@ -0,0 +1,477 @@
+/*
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Functions to serialise most of the types/classed used in Orxonox
+*/
+
+#ifndef _Serialise_H__
+#define _Serialise_H__
+
+#include <cstring>
+#include "util/Math.h"
+
+namespace orxonox{
+    
+// general template declaration
+    
+    /** @brief returns the size of the variable in a datastream */
+    template <class T> inline uint32_t returnSize( const T& );
+    /** @brief loads the value of a variable out of the bytestream and increases the mem pointer */
+    template <class T> inline void loadAndIncrease( const T&, uint8_t*& );
+    /** @brief saves the value of a variable into the bytestream and increases the mem pointer */
+    template <class T> inline void saveAndIncrease( const T&, uint8_t*& );
+    /** @brief checks whether the variable of type T is the same as in the bytestream */
+    template <class T> inline  bool checkEquality( const T&, uint8_t* );
+
+// =================== Template specialisation stuff =============
+
+// =========== bool
+
+    template <> inline uint32_t returnSize( const bool& variable )
+    {
+        return sizeof(uint8_t);
+    }
+
+    template <> inline void loadAndIncrease( const bool& variable, uint8_t*& mem )
+    {
+        *(uint8_t*)( &variable ) = *static_cast<uint8_t*>(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const bool& variable, uint8_t*& mem )
+    {
+        *static_cast<uint8_t*>(mem) = *(uint8_t*)( &variable );
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const bool& variable, uint8_t* mem )
+    {
+        return *static_cast<uint8_t*>(mem) == *(uint8_t*)( &variable );
+    }
+
+// =========== char
+
+    template <> inline uint32_t returnSize( const char& variable )
+    {
+        return sizeof(uint8_t);
+    }
+
+    template <> inline void loadAndIncrease( const char& variable, uint8_t*& mem )
+    {
+        *(uint8_t*)( &variable ) = *static_cast<uint8_t*>(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const char& variable, uint8_t*& mem )
+    {
+        *static_cast<uint8_t*>(mem) = *(uint8_t*)( &variable );
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const char& variable, uint8_t* mem )
+    {
+        return *static_cast<uint8_t*>(mem) == *(uint8_t*)( &variable );
+    }
+
+// =========== unsigned char
+
+    template <> inline uint32_t returnSize( const unsigned char& variable )
+    {
+        return sizeof(uint8_t);
+    }
+
+    template <> inline void loadAndIncrease( const unsigned char& variable, uint8_t*& mem )
+    {
+        *(uint8_t*)( &variable ) = *static_cast<uint8_t*>(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const unsigned char& variable, uint8_t*& mem )
+    {
+        *static_cast<uint8_t*>(mem) = *(uint8_t*)( &variable );
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const unsigned char& variable, uint8_t* mem )
+    {
+        return *static_cast<uint8_t*>(mem) == *(uint8_t*)( &variable );
+    }
+
+// =========== short
+
+    template <> inline uint32_t returnSize( const short& variable )
+    {
+        return sizeof(int16_t);
+    }
+
+    template <> inline void loadAndIncrease( const short& variable, uint8_t*& mem )
+    {
+        *(short*)( &variable ) = *(int16_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const short& variable, uint8_t*& mem )
+    {
+        *(int16_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const short& variable, uint8_t* mem )
+    {
+        return *(int16_t*)(mem) == static_cast<int16_t>(variable);
+    }
+
+// =========== unsigned short
+
+    template <> inline uint32_t returnSize( const unsigned short& variable )
+    {
+        return sizeof(uint16_t);
+    }
+
+    template <> inline void loadAndIncrease( const unsigned short& variable, uint8_t*& mem )
+    {
+        *(unsigned short*)( &variable ) = *(uint16_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const unsigned short& variable, uint8_t*& mem )
+    {
+        *(uint16_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const unsigned short& variable, uint8_t* mem )
+    {
+        return *(uint16_t*)(mem) == variable;
+    }
+
+// =========== int
+
+    template <> inline uint32_t returnSize( const int& variable )
+    {
+        return sizeof(int32_t);
+    }
+
+    template <> inline void loadAndIncrease( const int& variable, uint8_t*& mem )
+    {
+        *(int *)( &variable ) = *(int32_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const int& variable, uint8_t*& mem )
+    {
+        *(int32_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const int& variable, uint8_t* mem )
+    {
+        return *(int32_t*)(mem) == variable;
+    }
+
+// =========== unsigned int
+
+    template <> inline uint32_t returnSize( const unsigned int& variable )
+    {
+        return sizeof(uint32_t);
+    }
+    
+    template <> inline void loadAndIncrease( const unsigned int& variable, uint8_t*& mem )
+    {
+        *(unsigned int*)( &variable ) = *(uint32_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const unsigned int& variable, uint8_t*& mem )
+    {
+        *(uint32_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const unsigned int& variable, uint8_t* mem )
+    {
+        return *(uint32_t*)(mem) == variable;
+    }
+
+// =========== long
+
+    template <> inline uint32_t returnSize( const long& variable )
+    {
+        return sizeof(int32_t);
+    }
+
+    template <> inline void loadAndIncrease( const long& variable, uint8_t*& mem )
+    {
+        *(long*)( &variable ) = *(int32_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const long& variable, uint8_t*& mem )
+    {
+        *(int32_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const long& variable, uint8_t* mem )
+    {
+        return *(int32_t*)(mem) == variable;
+    }
+
+// =========== unsigned long
+
+    template <> inline uint32_t returnSize( const unsigned long& variable )
+    {
+        return sizeof(uint32_t);
+    }
+
+    template <> inline void loadAndIncrease( const unsigned long& variable, uint8_t*& mem )
+    {
+        *(unsigned long*)( &variable ) = *(uint32_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const unsigned long& variable, uint8_t*& mem )
+    {
+        *(uint32_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const unsigned long& variable, uint8_t* mem )
+    {
+        return *(uint32_t*)(mem) == variable;
+    }
+
+// =========== long long
+
+    template <> inline uint32_t returnSize( const long long& variable )
+    {
+        return sizeof(int64_t);
+    }
+
+    template <> inline void loadAndIncrease( const long long& variable, uint8_t*& mem )
+    {
+        *(long long*)( &variable ) = *(int64_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const long long& variable, uint8_t*& mem )
+    {
+        *(int64_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const long long& variable, uint8_t* mem )
+    {
+        return *(int64_t*)(mem) == variable;
+    }
+
+// =========== unsigned long long
+
+    template <> inline uint32_t returnSize( const unsigned long long& variable )
+    {
+        return sizeof(uint64_t);
+    }
+
+    template <> inline void loadAndIncrease( const unsigned long long& variable, uint8_t*& mem )
+    {
+        *(unsigned long long*)( &variable ) = *(uint64_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const unsigned long long& variable, uint8_t*& mem )
+    {
+        *(uint64_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const unsigned long long& variable, uint8_t* mem )
+    {
+        return *(uint64_t*)(mem) == variable;
+    }
+
+// =========== float
+
+    template <> inline uint32_t returnSize( const float& variable )
+    {
+        return sizeof(uint32_t);
+    }
+
+    template <> inline void loadAndIncrease( const float& variable, uint8_t*& mem )
+    {
+        *(uint32_t*)( &variable ) = *(uint32_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const float& variable, uint8_t*& mem )
+    {
+        *(uint32_t*)(mem) = *(uint32_t*)( &variable );
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const float& variable, uint8_t* mem )
+    {
+        return *(uint32_t*)(mem) == *(uint32_t*)( &variable );
+    }
+
+// =========== double
+
+    template <> inline uint32_t returnSize( const double& variable )
+    {
+        return sizeof(uint64_t);
+    }
+
+    template <> inline void loadAndIncrease( const double& variable, uint8_t*& mem )
+    {
+        *(uint64_t*)( &variable ) = *(uint64_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const double& variable, uint8_t*& mem )
+    {
+        *(uint64_t*)(mem) = *(uint64_t*)( &variable );
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const double& variable, uint8_t* mem )
+    {
+        return *(uint64_t*)(mem) == *(uint64_t*)( &variable );
+    }
+
+// =========== long double
+
+    template <> inline uint32_t returnSize( const long double& variable )
+    {
+        return sizeof(uint64_t);
+    }
+
+    template <> inline void loadAndIncrease( const long double& variable, uint8_t*& mem )
+    {
+        double temp;
+        memcpy(&temp, mem, sizeof(uint64_t));
+        *(long double*)( &variable ) = static_cast<const long double>(temp);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const long double& variable, uint8_t*& mem )
+    {
+        double temp = static_cast<double>(variable);
+        memcpy(mem, &temp, sizeof(uint64_t));
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const long double& variable, uint8_t* mem )
+    {
+        double temp = static_cast<double>(variable);
+        return memcmp(&temp, mem, sizeof(uint64_t))==0;
+    }
+
+// =========== string
+
+    template <> inline uint32_t returnSize( const std::string& variable )
+    {
+        return variable.length()+1;
+    }
+
+    template <> inline void saveAndIncrease( const std::string& variable, uint8_t*& mem )
+    {
+        memcpy(mem, variable.c_str(), variable.length()+1);
+        mem += variable.length()+1;
+    }
+
+    template <> inline void loadAndIncrease( const std::string& variable, uint8_t*& mem )
+    {
+        *(std::string*)( &variable ) = std::string((const char *)mem);
+        mem += variable.length()+1;
+    }
+
+    template <> inline bool checkEquality( const std::string& variable, uint8_t* mem )
+    {
+        return std::string((const char*)mem)==variable;
+    }
+
+// =========== Degree
+
+    template <> inline uint32_t returnSize( const Degree& variable )
+    {
+        return sizeof(Ogre::Real);
+    }
+
+    template <> inline void saveAndIncrease( const Degree& variable, uint8_t*& mem )
+    {
+        Ogre::Real r = variable.valueDegrees();
+        memcpy(mem, &r, returnSize( variable ));
+        mem += returnSize( variable );
+    }
+
+    template <> inline void loadAndIncrease( const Degree& variable, uint8_t*& mem )
+    {
+        Ogre::Real* r = (Ogre::Real*)mem;
+        (Degree&)variable = *r;
+        mem += returnSize( variable );
+    }
+
+     template <> inline bool checkEquality( const Degree& variable, uint8_t* mem )
+    {
+        Ogre::Real* r = (Ogre::Real*)mem;
+        return variable==Degree(*r);
+    }
+
+// =========== Radian
+
+    template <> inline uint32_t returnSize( const Radian& variable )
+    {
+        return sizeof(Ogre::Real);
+    }
+
+    template <> inline void saveAndIncrease( const Radian& variable, uint8_t*& mem )
+    {
+        Ogre::Real r = variable.valueRadians();
+        memcpy(mem, &r, returnSize( variable ));
+        mem += returnSize( variable );
+    }
+
+    template <> inline void loadAndIncrease( const Radian& variable, uint8_t*& mem )
+    {
+        Ogre::Real* r = (Ogre::Real*)mem;
+        (Radian&)variable = *r;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const Radian& variable, uint8_t* mem )
+    {
+        Ogre::Real* r = (Ogre::Real*)mem;
+        return variable==Degree(*r);
+    }
+    
+    
+}
+
+
+#endif
