changeset 7:f1aed00851e7

=branch zu trunk gemacht
author wuha
date Thu, 25 Sep 2008 11:05:55 +0000
parents 7e04df9d6938
children c6b70b00dc95
files src/core/charconv.h src/core/clientnetwork.cpp src/core/command.cpp src/core/command.h src/core/creature.cpp src/core/dmgprojectile.cpp src/core/document.cpp src/core/document.h src/core/dropitem.cpp src/core/event.h src/core/item.cpp src/core/item.h src/core/itemlist.cpp src/core/network.cpp src/core/player.cpp src/core/player.h src/core/region.cpp src/core/region.h src/core/serveritem.cpp src/core/serveritem.h src/core/servernetwork.cpp src/core/world.cpp src/core/world.h src/core/worldobject.h src/gl_gui/window_main_gl.cpp src/gl_gui/window_main_gl.h src/gui/config src/gui/main_gui.cpp src/gui/mainwindow.cpp src/gui/mainwindow.h src/gui/scene.cpp
diffstat 31 files changed, 655 insertions(+), 268 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/charconv.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/charconv.h	Thu Sep 25 11:05:55 2008 +0000
@@ -48,8 +48,8 @@
 		if (packet->data[0] == ID_TIMESTAMP)
 		{
 			char tmp;
-			fromBuffer(tmp);
-			fromBuffer(m_timestamp);
+			m_bitstream.Read(tmp);
+			m_bitstream.Read(m_timestamp);
 		}
 		else
 		{
@@ -144,6 +144,11 @@
 		return RakNet::GetTime()-m_timestamp;
 	}
 	
+	unsigned long getTimestamp()
+	{
+		return m_timestamp;
+	}
+	
 	
 	private:
 		/**
--- a/src/core/clientnetwork.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/clientnetwork.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -4,6 +4,10 @@
 ClientNetwork::ClientNetwork()
 	: Network()
 {
+	SocketDescriptor sock;
+	
+	m_peer->Startup(1,10,&sock, 1);
+	
 	m_server_address = UNASSIGNED_SYSTEM_ADDRESS;
 	m_status = NET_CLOSE;
 }
--- a/src/core/command.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/command.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -20,5 +20,16 @@
 	cv->fromBuffer(m_range);
 	m_damage_mult =1;	
 }
+		
+		
+bool Command::operator!=(Command& other)
+{
+	return (m_type != other.m_type || m_goal_object_id != other.m_goal_object_id 
+			|| m_goal_coordinate_x != other.m_goal_coordinate_x
+			|| m_goal_coordinate_y != other.m_goal_coordinate_y);
+			
+	
+}
 
 
+
--- a/src/core/command.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/command.h	Thu Sep 25 11:05:55 2008 +0000
@@ -82,6 +82,12 @@
 	 * \return Zeiger hinter den gelesenen Datenbereich
 	 */
 	virtual void fromString(CharConv* cv);
+	
+	/**
+	 * \fn bool operator!=(Command& other)
+	 * \brief Vergleichsoperator auf Ungleichheit
+	 */
+	bool operator!=(Command& other);
 
 	/**
 	 * \fn Command()
--- a/src/core/creature.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/creature.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -2365,7 +2365,7 @@
 	// besondere zeitabhaengige Effekte berechnen
 	if (getWorld()->isServer())
 	{
-		if (m_base_attr_mod.m_special_flags & FLAMEARMOR && getWorld()->timerLimit(2))
+		if (m_base_attr_mod.m_special_flags & FLAMEARMOR && getWorld()->timerLimit(1))
 		{
 			// Flammenruestung
 			
@@ -2409,7 +2409,7 @@
 	// Statusmods behandeln
 	if (getState()==STATE_ACTIVE)
 	{
-		if (getWorld()->isServer() && getWorld()->timerLimit(2))
+		if (getWorld()->isServer() && getWorld()->timerLimit(1))
 		{
 			// Vergiftet
 			if (m_dyn_attr.m_status_mod_time[Damage::POISONED]>0)
@@ -4200,16 +4200,24 @@
 		DEBUG5("got Command %i",m_command.m_type);
 	}
 	
+	float  atime = m_action.m_time - m_action.m_elapsed_time;
+	float etime = m_action.m_elapsed_time;
 	char oldact = m_action.m_type;
 	float posx = getGeometry()->m_shape.m_coordinate_x;
 	float posy = getGeometry()->m_shape.m_coordinate_y;
 	float movex = getMoveInfo()->m_speed_x;
 	float movey = getMoveInfo()->m_speed_y;
+	float oldgoalx = posx + movex*atime;
+	float oldgoaly = posy + movey*atime;
+	
 	float newx = getGeometry()->m_shape.m_coordinate_x,newy= getGeometry()->m_shape.m_coordinate_y;
 	float newmovex,newmovey;
 	
 	bool newact= false;
 	bool newmove = false;
+	
+	
+	
 	if (event->m_data & Event::DATA_ACTION)
 	{
 		
@@ -4335,13 +4343,24 @@
 		
 		DEBUG5("goal %f %f current pos %f %f",goalx,goaly,getGeometry()->m_shape.m_coordinate_x,getGeometry()->m_shape.m_coordinate_y);
 		
+		/*
+		timeval tv;
+		gettimeofday(&tv, NULL);
+		DEBUG("time elapsed ingame %f delay %i system time %i",etime,cv->getDelay(),tv.tv_usec/1000);
+		*/
 		// Zeit die zum erreichen des Zieles uebrig ist
 		float goaltime = acttime;
 		if (event->m_data & Event::DATA_ACTION)
 		{
 			goaltime -= cv->getDelay();
 		}
-		DEBUG5("time to reach goal %f",goaltime);
+		if (goaltime < 100)
+		{
+			
+			DEBUG5("time to reach goal %f (prev time %f) delay %i",goaltime,atime,cv->getDelay());
+			
+		}
+		DEBUG5("previously planned time %f",atime);
 		
 		if (goaltime <0)
 		{
@@ -4361,10 +4380,26 @@
 	if (newact)
 	{
 		m_action.m_elapsed_time += cv->getDelay();	
-		if (!newmove)
+		if (!newmove && m_action.m_type != Action::NOACTION)
 		{
 			moveTo(newx,newy);
 		}
+		
+		if (Action::getActionInfo(m_action.m_type)->m_distance != Action::SELF)
+		{
+			float x = getGeometry()->m_shape.m_coordinate_x;
+			float y = getGeometry()->m_shape.m_coordinate_y;
+			float goalx =  m_action.m_goal_coordinate_x;
+			float goaly =  m_action.m_goal_coordinate_y;
+
+			getGeometry()->m_angle = atan2(goaly-y,goalx-x);
+
+		}
+		if (Action::getActionInfo(m_action.m_type)->m_base_action == Action::WALK)
+		{
+			getGeometry()->m_angle = atan2(getMoveInfo()->m_speed_y,getMoveInfo()->m_speed_x);
+
+		}
 	}
 }
 
--- a/src/core/dmgprojectile.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/dmgprojectile.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -272,7 +272,7 @@
 		}
 	}
 
-	if (m_type == FIRE_WALL && m_world->timerLimit(2))
+	if (m_type == FIRE_WALL && m_world->timerLimit(1))
 	{
 		// Typ Feuersaeule
 
@@ -454,7 +454,11 @@
 				m_speed_x=newdir[0];
 				m_speed_y=newdir[1];
 			}
-			m_event_mask |= Event::DATA_SPEED;
+			
+			if (m_world->timerLimit(0))
+			{
+				m_event_mask |= Event::DATA_SPEED;
+			}
 		}
 		hitobj.clear();
 		
@@ -559,7 +563,7 @@
 			// zufaelliges weiterspringen, Chance 50%
 			if (rand()<RAND_MAX*0.5)
 			{
-
+				DEBUG("prob bounce");
 				bounce = true;
 			}
 		}
@@ -633,7 +637,7 @@
 				m_speed_x = dir[0] *speed;
 				m_speed_y = dir[1] *speed;
 
-				m_event_mask |= Event::DATA_SPEED;
+				m_event_mask |= Event::DATA_SPEED | Event::DATA_PROJ_STATE;
 
 				DEBUG5("koord %f %f to %f %f",xnew,ynew,x2,y2);
 				DEBUG5("dir %f %f",dir[0],dir[1]);
--- a/src/core/document.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/document.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -350,6 +350,7 @@
 
 void Document::onButtonSaveExitClicked ( )
 {
+	
 	if (m_state!=SHUTDOWN_REQUEST)
 	{
 		setState(SHUTDOWN_REQUEST);
@@ -358,6 +359,8 @@
 	{
 		setState(SHUTDOWN);
 	}
+	
+	m_shutdown_timer =0;
 
 	ClientCommand command;
 
@@ -459,6 +462,10 @@
 	
 	
 	int id = getObjectAt(x,y);
+	if (getGUIState()->m_cursor_object_id != 0)
+	{
+		id = getGUIState()->m_cursor_object_id;
+	}
 	
 	m_gui_state.m_clicked_object_id = id;
 	command.m_id =id;
@@ -466,7 +473,7 @@
 
 	if (command.m_id!=0)
 	{
-		DEBUG5("angeklicktes Objekt %i",command.m_id);
+		DEBUG("angeklicktes Objekt %i",command.m_id);
 	}
 
 	if (command.m_id ==0 && m_gui_state.m_cursor_item_id!=0)
@@ -935,7 +942,10 @@
 void Document::update(float time)
 {
 	// Welt eine Zeitscheibe weiter laufen lassen
-	m_world->update(time);
+	if (m_world != 0)
+	{
+		m_world->update(time);
+	}
 	
 	DEBUG5("modified is %i",m_modified);
 	DEBUG5("State is %i",m_state);
@@ -968,6 +978,11 @@
 
 		case SHUTDOWN_REQUEST:
 			updateContent(time);
+			m_shutdown_timer += time;
+			if (m_shutdown_timer>400)
+			{
+				setState(SHUTDOWN);
+			}
 			break;
 
 		case SHUTDOWN_WRITE_SAVEGAME:
--- a/src/core/document.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/document.h	Thu Sep 25 11:05:55 2008 +0000
@@ -817,7 +817,13 @@
 	 * \var Timer m_timer
 	 * \brief Timer fuer die Updatezyklen der Spielwelt
 	 */
-	Timer m_timer;	
+	Timer m_timer;
+	
+	/**
+	 * \var m_shutdown_timer
+	 * \brief Timer fuer Shutdown
+	 */
+	float m_shutdown_timer;
 
 };
 
--- a/src/core/dropitem.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/dropitem.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -3,7 +3,7 @@
 void DropItem::toString(CharConv* cv)
 {
 
-	m_item->toString(cv,0);
+	m_item->toString(cv);
 	cv->toBuffer(m_x);
 	cv->toBuffer(m_y);
 	
@@ -15,7 +15,7 @@
 {
 	short pos;
 	
-	m_item->fromString(cv,pos);
+	m_item->fromString(cv);
 	cv->fromBuffer<short>(m_x );
 	cv->fromBuffer<short>(m_y);
 	
--- a/src/core/event.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/event.h	Thu Sep 25 11:05:55 2008 +0000
@@ -22,6 +22,13 @@
 		PLAYER_JOINED = 10,
 		PLAYER_QUIT = 11,
 		PLAYER_CHANGED_REGION = 12,
+  
+		PLAYER_ITEM_EQUIPED = 20,
+		PLAYER_NOITEM_EQUIPED = 21,
+		
+		ITEM_DROPPED = 30,
+		ITEM_REMOVED = 31,
+		
 	};
 	
 	/**
--- a/src/core/item.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/item.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -13,107 +13,11 @@
 
 string Item::getString()
 {
-	/*
-	switch (m_type)
-	{
-		case NOITEM:
-			return "noitem";
-			break;
-		case ARMOR:
-			switch (m_subtype)
-			{
-				case LEATHER_ARMOR:
-					return "leather_armor";
-				case TILED_ARMOR:
-					return "tiled_armor";
-				case HEAVY_ARMOR:
-					return "heavy_armor";
-
-				default:
-					return "armor";
-			}
-			break;
-		case HELMET:
-			switch (m_subtype)
-			{
-				case STEEL_HELMET:
-					return "steel_helmet";
-				case DIVINE_HELMET:
-					return "divine_helmet";
-
-				default:
-					return "helmet";
-			}
-			break;
-		case GLOVES:
-			return "gloves";
-			break;
-		case WEAPON:
-			switch (m_subtype)
-			{
-				case SHORT_SWORD:
-					return "short_sword";
-				case LONG_SWORD:
-					return "long_sword";
-				case WOODEN_BOW:
-					return "wooden_bow";
-				case LONG_BOW:
-					return "long_bow";
-				case BURNING_BOW:
-					return "burning_bow";
-				case BATTLE_AXE:
-					return "battle_axe";
-				case HOLY_FLAIL:
-					return "holy_flail";
-
-				default:
-					return "weapon";
-			}
-			break;
-		case SHIELD:
-			switch (m_subtype)
-			{
-				case WOODEN_SHIELD:
-					return "wooden_shield";
-				case IRON_SHIELD:
-					return "iron_shield";
-
-				default:
-					return "shield";
-			}
-			break;
-		case POTION:
-			switch (m_subtype)
-			{
-				case SMALL_HEAL_POTION:
-					return "small_heal_potion";
-				case BIG_HEAL_POTION:
-					return "big_heal_potion";
-				case HEAL_BLIND_POTION:
-					return "heal_blind_potion";
-				case UNFREEZE_POTION:
-					return "instant_unfreeze_potion";
-
-				default:
-					return "potion";
-			}
-			break;
-		case RING:
-			return "ring";
-			break;
-		case AMULET:
-			return "amulet";
-			break;
-		default:
-			return "unknown";
-			break;
-	}
-	*/
 	return m_subtype;
 }
 
 
-void Item::toString(CharConv* cv, short pos)
+void Item::toString(CharConv* cv)
 {
 
 	cv->toBuffer((char) m_type);
@@ -121,26 +25,13 @@
 	stmp[10] = '\0';
 	strncpy(stmp,m_subtype.c_str(),10);
 	cv->toBuffer(stmp,10);
-	cv->toBuffer((char) m_size);
-	cv->toBuffer(pos);
 
 
 }
 
-void Item::fromString(CharConv* cv, short& pos)
+void Item::fromString(CharConv* cv)
 {
-	char ctmp;
-	short tmp;
-	cv->fromBuffer<char>(ctmp);
-	m_type = (Type) ctmp;
-	char stmp[11];
-	stmp[10] ='\0';
-	cv->fromBuffer(stmp,10);
-	m_subtype = stmp;
-	cv->fromBuffer<char>(ctmp);
-	m_size = (Size) ctmp;
-	cv->fromBuffer<short>(pos);
-
+	// Daten werden extern eingelesen
 }
 
 
--- a/src/core/item.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/item.h	Thu Sep 25 11:05:55 2008 +0000
@@ -155,21 +155,21 @@
 	virtual string getString();
 
 	/**
-	 * \fn void toString(CharConv* cv, short pos)
+	 * \fn void toString(CharConv* cv)
 	 * \brief Konvertiert das Objekt in einen String und schreibt ihn in der Puffer
 	 * \param buf Ausgabepuffer
 	 * \return Zeiger hinter den beschriebenen Datenbereich
 	 */
-	virtual void toString(CharConv* cv, short pos);
+	virtual void toString(CharConv* cv);
 
 
 	/**
-	 * \fn void fromString(void CharConv* cv, short& pos)
+	 * \fn void fromString(void CharConv* cv)
 	 * \brief Erzeugt das Objekt aus einem String
 	 * \param buf Objekt als String
 	 * \return Zeiger hinter den gelesenen Datenbereich
 	 */
-	virtual void fromString(CharConv* cv,short& pos);
+	virtual void fromString(CharConv* cv);
 
 
 	/**
--- a/src/core/itemlist.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/itemlist.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -498,7 +498,7 @@
 	
 void Equipement::toString(CharConv* cv, int & nr, bool secondary_equip)
 {
-
+/*
 	nr=0;
 	// Ausruestungsgegenstaende
 	if (m_armor)
@@ -601,7 +601,7 @@
 			nr++;
 		}
 	}
-	
+*/
 	
 
 }
@@ -609,7 +609,7 @@
 void Equipement::fromString(CharConv* cv, int nr)
 {	
 
-	
+/*
 	int i;
 	short pos;
 	Item* it;
@@ -625,7 +625,7 @@
 		swapItem(it,pos);
 	}
 	
-	
+	*/
 
 }
 
--- a/src/core/network.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/network.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -4,12 +4,12 @@
 Network::Network()
 {
 	m_peer = RakNetworkFactory::GetRakPeerInterface();
-	SocketDescriptor sock;
+	
+	m_peer->SetOccasionalPing(true);
 	
-	m_peer->Startup(1,10,&sock, 1);
-	
-	m_peer->ApplyNetworkSimulator( 0, 200, 0);
-	
+	// m_peer->ApplyNetworkSimulator( 0, 100, 0);
+	// m_peer->ApplyNetworkSimulator( 0, 100, 500);
+	// m_peer->ApplyNetworkSimulator( 0, 100, 2000);
 }
 
 
--- a/src/core/player.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/player.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -420,7 +420,7 @@
 			else
 			{
 			// Item soll im Inventar abgelegt werden
-			DEBUG("swap in inventory");
+			DEBUG5("swap in inventory");
 
 			// Groesse die das Item haben muss
 				Item::Size size = Item::BIG;
@@ -456,6 +456,25 @@
 
 		// Vertauschen von Cursoritem und angeklicktem Item
 		m_equipement->swapCursorItem(pos);
+		
+		if (getWorld()->isServer() && pos <Equipement::CURSOR_ITEM)
+		{
+			// Ausruestungsgegenstand wurde getauscht
+			Event event;
+			event.m_id = getId();
+			event.m_data = pos;
+			
+			if (m_equipement->getItem(pos) == 0)
+			{
+				event.m_type = Event::PLAYER_NOITEM_EQUIPED;
+			}
+			else
+			{
+				event.m_type = Event::PLAYER_ITEM_EQUIPED;
+			}
+			DEBUG("event: %i at %i",event.m_type,event.m_data);
+			getWorld()->insertEvent(event);
+		}
 
 		Item* itm;
 		if (pos==Equipement::WEAPON || pos == Equipement::WEAPON2)
@@ -472,6 +491,18 @@
 					if (pos == Equipement::WEAPON2)
 						shpos = Equipement::SHIELD2;
 					
+					if (getWorld()->isServer())
+					{
+						Event event;
+						event.m_type =  Event::PLAYER_NOITEM_EQUIPED;
+						event.m_data = shpos;
+						event.m_id = getId();
+							
+						DEBUG5("event: no item at %i",shpos);
+							
+						getWorld()->insertEvent(event);
+					}
+					
 					// Wenn aktuell kein Item am Cursor gehalten wird
 					if (m_equipement->getItem(Equipement::CURSOR_ITEM)==0)
 					{
@@ -485,6 +516,9 @@
 						// Schild aus dem Schildslot holen
 						m_equipement->swapItem( itm,shpos);
 						
+						// wenn man sich auf Serverseite befindet: Event generieren
+						
+						
 						if (!getEquipement()->insertItem(itm))
 						{
 							// Einfuegen ins Inventar fehlgeschlagen
@@ -508,6 +542,18 @@
 				short wpos= Equipement::WEAPON;
 				if (pos == Equipement::SHIELD2)
 					wpos = Equipement::WEAPON2;
+				
+				if (getWorld()->isServer())
+				{
+					Event event;
+					event.m_type =  Event::PLAYER_NOITEM_EQUIPED;
+					event.m_data = wpos;
+					event.m_id = getId();
+							
+					DEBUG5("event: no item at %i",wpos);
+							
+					getWorld()->insertEvent(event);
+				}
 			
 				m_equipement->swapCursorItem(wpos);
 			}
@@ -680,7 +726,7 @@
 }
 
 
-bool Player::onClientCommand( ClientCommand* command)
+bool Player::onClientCommand( ClientCommand* command, float delay)
 {
 	DEBUG5("Kommando (%f %f) button: %i id: %i action: %i",command->m_coordinate_x,command->m_coordinate_y,command->m_button,command->m_id, command->m_action);
 
@@ -694,6 +740,10 @@
 	
 	// prob_size, min level, max_level, prob_magic, magic_power
 	ds.init(prob, 0,20, 0.3, 2000);
+	
+	// Kopie des aktuellen Kommandos anlegen
+	Command oldcommand;
+	memcpy(&oldcommand,getNextCommand(),sizeof(Command));
 
 	switch(command->m_button)
 	{
@@ -748,8 +798,8 @@
 			break;
 
 		case BUTTON_SAVE_QUIT:
-			DEBUG("players wants to quit, sending savegame");
-			sendSavegame();
+			setState(STATE_QUIT);
+			DEBUG("player wants to quit");
 			break;
 
 		case BUTTON_SWAP_EQUIP:
@@ -885,6 +935,73 @@
 
 		default: ;
 	}
+	
+	if (oldcommand != *getNextCommand() && delay>0)
+	{
+		// naechstes Kommando hat sich geaendert
+		// die aktuelle Aktion basiert eventuell auf einem veralteten Kommando
+		
+		if (getAction()->m_type == Action::NOACTION || getAction()->m_elapsed_time < delay)
+		{
+			// Aktion basiert auf veraltetem Kommando
+			// abbrechen
+			abortAction();
+			
+			// neue Aktion berechnen
+			calcAction();
+			initAction();
+			calcDamage(getAction()->m_type,*(getDamage()));
+			
+			DEBUG5("new action %i time %f",getAction()->m_type,getAction()->m_time);
+			
+			// Action entsprechend der Verzoegerung schneller ausfuehren
+			// aber maximal doppelt so schnell
+			float mult = std::max(getAction()->m_time-delay, getAction()->m_time/2)/getAction()->m_time;
+			DEBUG5("delay %f mult %f",delay,mult);
+			if (getAction()->m_type == Action::WALK)
+			{
+				// Laufgeschwindigkeit entsprechend erhoehen
+				getMoveInfo()->m_speed_x /= mult;
+				getMoveInfo()->m_speed_y /= mult;
+					
+			}
+			getAction()->m_time *= mult;
+			DEBUG5("faster action time %i",getAction()->m_time);
+		}
+		
+	}
+}
+
+
+void Player::abortAction()
+{
+	float time = getAction()->m_elapsed_time;
+	Action::ActionInfo* aci = Action::getActionInfo(getAction()->m_type);
+
+	DEBUG5("abort Action %i (elapsed time %f)",getAction()->m_type, time);
+
+	
+	if (getAction()->m_type == Action::WALK)
+	{
+		// Position zurueck setzen
+		getGeometry()->m_shape.m_coordinate_x -= getMoveInfo()->m_speed_x*time;
+		getGeometry()->m_shape.m_coordinate_y -= getMoveInfo()->m_speed_y*time;
+	}
+	
+	// Timer wieder zuruecksetzen
+	if (aci->m_timer_nr==1)
+	{
+		 m_timer1=0;
+		 m_timer1_max=0;
+	}
+	
+	if (aci->m_timer_nr==2)
+	{
+		m_timer2=0;
+		m_timer2_max=0;
+	}
+	
+	m_event_mask |= Event::DATA_ACTION;
 }
 
 bool Player::update(float time)
@@ -1550,22 +1667,29 @@
 	
 	cv->toBuffer(getBaseAttr()->m_level);
 	
-		
-
-	/*
-#define hex(a) ((a)>=10) ? (a)-10+'a' : (a)+'0'
-	unsigned char* cp;
-	for (int i=-12;i<25;i++)
+	// Items
+	char cnt =0;
+	Item* item;
+	for ( short i = Equipement::ARMOR; i<= Equipement::SHIELD2; i++)
 	{
-		cp = (unsigned char*) buf+i;
-		//if (i%10==8)
-		//	printf("\n %p\n",cp);
-
-		printf("%c%c ",hex(*cp/16),hex(*cp%16));
-
+		item = getEquipement()->getItem(i);
+		if (item !=0)
+			cnt++;
 	}
-	printf("\n\n");
-*/
+	DEBUG5("number of items: %i",cnt);
+	cv->toBuffer(cnt);
+	
+	
+	for ( short i = Equipement::ARMOR; i<= Equipement::SHIELD2; i++)
+	{
+		item = getEquipement()->getItem(i);
+		if (item !=0)
+		{
+			cv->toBuffer(i);
+			item->toString(cv);
+			
+		}
+	}
 
 }
 
@@ -1580,9 +1704,38 @@
 	
 	cv->fromBuffer(getBaseAttr()->m_level);
 	
+	char cnt;
+	cv->fromBuffer(cnt);
+	DEBUG5("number of items: %i",cnt);
+	
+	
+	for ( short i = 0; i< cnt; i++)
+	{
+		readItem(cv);
+	}
 	
 }
 
+void Player::readItem(CharConv* cv)
+{
+	short pos;
+	char type;
+	char subtype[11];
+	subtype[10] ='\0';
+	Item* item;
+	
+	cv->fromBuffer<short>(pos);
+	cv->fromBuffer<char>(type);
+	cv->fromBuffer(subtype,10);
+	
+		
+	item = ItemFactory::createItem((Item::Type) type, std::string(subtype));
+	item->fromString(cv);
+	getEquipement()->swapItem(item,pos);
+		
+	if (item !=0)
+		delete item;
+}
 
 void Player::toStringComplete(CharConv* cv)
 {
@@ -1810,6 +1963,7 @@
 
 void Player::writeEquipement(CharConv* cv)
 {
+	/*
 	ServerItem* it;
 
 	short nr=0;
@@ -1835,11 +1989,12 @@
 	}
 
 	DEBUG5("written %i items",nr);
-
+	*/
 }
 
 void Player::loadEquipement(CharConv* cv)
 {
+	/*
 	m_equipement->clear();
 	ServerItem* it;
 	Item* itm;
@@ -1858,7 +2013,7 @@
 		itm  = it;
 		m_equipement->swapItem(itm,pos);
 	}
-
+	*/
 }
 
 
--- a/src/core/player.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/player.h	Thu Sep 25 11:05:55 2008 +0000
@@ -161,9 +161,10 @@
 	 * \fn bool onClientCommand( ClientCommand* command)
 	 * \brief  Reaktion auf eine Anweisung des Nutzers
 	 * \param command Kommando des Nutzers
+	 * \param delay Millisekunden die das Kommando verspaetet erhalten wurde
 	 * \return bool gibt an, ob die Behandlung fehlerfrei verlaufen ist
 	 */
-	bool onClientCommand( ClientCommand* command);
+	bool onClientCommand( ClientCommand* command, float delay =0);
 	
 	/**
 	 * \fn bool onGamefieldClick(ClientCommand* command)
@@ -181,6 +182,12 @@
 	 */
 	bool onItemClick(ClientCommand* command);
 	
+	/**
+	 * \fn void abortAction()
+	 * \brief Bricht die aktuell angefangene Aktion ab
+	 */
+	void abortAction();
+	
 	
 	/**
 	 * \fn void sendSavegame()
@@ -234,6 +241,12 @@
 	virtual void toStringComplete(CharConv* cv);
 	
 	/**
+	 * \fn void readItem(CharConv* cv)
+	 * \brief Liest ein Item aus dem Bitstream und fuegt es ins Inventar ein
+	 */
+	void readItem(CharConv* cv);
+	
+	/**
 	 * \fn void writeEquipement(CharConv* cv)
 	 * \brief Schreibt des Inventar in den Puffer
 	 * \param buf Ausgabepuffer
--- a/src/core/region.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/region.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -772,9 +772,6 @@
 	map<int,DmgProjectile*>::iterator it3;
 	
 	
-	// alle bisherigen Events loeschen
-	m_events->clear();
-	
 	// alle Eventsmasken loeschen
 	for (iter =m_objects->begin(); iter!=m_objects->end(); ++iter)
 	{
@@ -951,6 +948,17 @@
 		kt->second->toString(cv);	
 	}
 	
+	cv->toBuffer<short>((short) m_drop_items->size());
+	DEBUG("dropped items: %i",m_drop_items->size());
+	
+	//  Items in den Puffer eintragen
+	map<int,DropItem*>::iterator lt;
+	for (lt = m_drop_items->begin(); lt != m_drop_items->end(); ++lt)
+	{
+		cv->toBuffer(lt->second->m_x);
+		cv->toBuffer(lt->second->m_y);
+		lt->second->m_item->toString(cv);
+	}
 }
 
 
@@ -1022,6 +1030,36 @@
 	insertProjectile(proj,x,y);
 }
 
+void Region::createItemFromString(CharConv* cv, int id)
+{
+	char type;
+	char subtype[11];
+	subtype[10] ='\0';
+	Item* item;
+	
+	cv->fromBuffer<char>(type);
+	cv->fromBuffer(subtype,10);
+		
+	item = ItemFactory::createItem((Item::Type) type, std::string(subtype));
+	item->fromString(cv);
+	
+	short sx = id / 10000;
+	short sy = id % 10000;
+	
+	DropItem* di = new DropItem;
+	di->m_item = item;
+	di->m_x = sx;
+	di->m_y = sy;
+	DEBUG5("dropped item %i", sx*10000+sy);
+	di->m_time = 0;
+			
+	Gridunit* gu = (m_data_grid->ind(sx/8,sy/8));
+			
+	gu->insertItem(di);
+	m_drop_items->insert(make_pair(id,di));
+}
+
+
 void Region::setRegionData(CharConv* cv,map<int,ServerWObject*>* players)
 {
 	// Groesse der Region wird schon vorher eingelesen
@@ -1082,20 +1120,7 @@
 	{
 		createObjectFromString(cv,players);
 	}
-	
-	/*
-	DEBUG("objects");
-	map<int,ServerWObject*>::iterator mt;
-	for (mt = m_static_objects->begin();mt!=m_static_objects->end();mt++)
-	{
-		DEBUG("%s id %i at %f %f",mt->second->getTypeInfo()->m_subtype.c_str(),mt->second->getId(), mt->second->getGeometry()->m_shape.m_coordinate_x,mt->second->getGeometry()->m_shape.m_coordinate_y);
-	}
-	
-	for (mt = m_objects->begin();mt!=m_objects->end();mt++)
-	{
-		DEBUG("%s id %i at %f %f",mt->second->getTypeInfo()->m_subtype.c_str(),mt->second->getId(), mt->second->getGeometry()->m_shape.m_coordinate_x,mt->second->getGeometry()->m_shape.m_coordinate_y);
-	}
-	*/
+
 	
 	// Anzahl der Projektile einlesen
 	short nr_proj;
@@ -1107,6 +1132,20 @@
 		createProjectileFromString(cv);
 	}
 	
+	// Anzahl Gegenstaende einlesen
+	short nr_items;
+	cv->fromBuffer<short>(nr_items);
+	DEBUG("items: %i",nr_items);
+	// Gegenstaende einlesen
+	short sx,sy;
+	for (int i=0; i<nr_items;i++)
+	{
+		cv->fromBuffer(sx);
+		cv->fromBuffer(sy);
+		createItemFromString(cv, sx*10000+sy);
+			
+	}
+	
 }
 
 
@@ -1184,6 +1223,15 @@
 			
 			DEBUG5("items dropped at %i %i",sx,sy);
 			
+			if (m_world->isServer())
+			{
+				Event event;
+				event.m_type = Event::ITEM_DROPPED;
+				event.m_id = i;
+				
+				insertEvent(event);
+			}
+			
 			return true;
 			
 		}
@@ -1314,6 +1362,16 @@
 		
 		m_drop_items->erase(it);
 		
+		// Event einfuegen, dass das Item entfernt wurde
+		if (m_world->isServer())
+		{
+			Event event;
+			event.m_type = Event::ITEM_REMOVED;
+			event.m_id = id;
+			
+			insertEvent(event);
+		}
+		
 		return true;
 	}
 }
--- a/src/core/region.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/region.h	Thu Sep 25 11:05:55 2008 +0000
@@ -227,6 +227,12 @@
 		void createProjectileFromString(CharConv* cv);
 		
 		/**
+		 * \fn void createItemFromString(CharConv* cv, int id)
+		 * \brief liest die Daten zu einem Gegenstand aus dem Bitstream und erzeugt es
+		 */
+		void createItemFromString(CharConv* cv, int id);
+		
+		/**
 		 * \fn void deleteProjectile(DmgProjectile* proj)
 		 * \brief Entfernt das Projektil aus der Region
 		 */
--- a/src/core/serveritem.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/serveritem.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -84,10 +84,10 @@
 	if (m_weapon_attr) delete  m_weapon_attr;
 }
 
-void ServerItem::toStringComplete(CharConv* cv, short pos)
+void ServerItem::toStringComplete(CharConv* cv)
 {
 
-	Item::toString(cv,pos);
+	Item::toString(cv);
 	
 	cv->toBuffer(m_price);
 	cv->toBuffer(m_level_req);
@@ -166,9 +166,9 @@
 	
 }
 
-void ServerItem::fromStringComplete(CharConv* cv, short& pos)
+void ServerItem::fromStringComplete(CharConv* cv)
 {
-	Item::fromString(cv,pos);	
+	Item::fromString(cv);	
 	
 	cv->fromBuffer<int>(m_price);
 	cv->fromBuffer<char>(m_level_req);
@@ -181,16 +181,25 @@
 	
 	if (mask & USEUP_INFO)
 	{
+		if (m_useup_effect !=0)
+			delete m_useup_effect;
+		
 		m_useup_effect= new CreatureDynAttrMod();
 	}
 	
 	if (mask & EQUIP_INFO)
 	{
+		if (m_equip_effect !=0)
+			delete m_equip_effect;
+		
 		m_equip_effect=new CreatureBaseAttrMod();
 	}
 
 	if (mask & WEAPON_INFO)
 	{
+		if (m_weapon_attr !=0)
+			delete m_weapon_attr;
+		
 		m_weapon_attr = new WeaponAttr();
 	}
 	
--- a/src/core/serveritem.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/serveritem.h	Thu Sep 25 11:05:55 2008 +0000
@@ -231,7 +231,7 @@
 	 * \param buf Ausgabepuffer
 	 * \return Zeiger hinter den beschriebenen Datenbereich
 	 */
-	void toStringComplete(CharConv* cv, short pos);
+	void toStringComplete(CharConv* cv);
 
 
 	/**
@@ -240,7 +240,7 @@
 	 * \param buf Zeiger auf Savegame
 	 * \return Zeiger hinter den Datenbereich
 	 */
-	void fromStringComplete(CharConv* cv, short& pos);
+	void fromStringComplete(CharConv* cv);
 
 
 	/**
--- a/src/core/servernetwork.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/servernetwork.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -37,6 +37,7 @@
 
 
 ServerNetwork::ServerNetwork(int max_slots)
+	: Network()
 {
 	m_max_slots = max_slots;
 
@@ -46,7 +47,6 @@
 {
 	DEBUG("init servernetwork");
 	
-	m_peer = RakNetworkFactory::GetRakPeerInterface();
 	SocketDescriptor sock(auth_port,0);
 
 	m_peer->Startup(m_max_slots /* max. Anzahl Verbindungen*/, 10/*sleep time*/, &sock, 1);
--- a/src/core/world.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/world.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -866,14 +866,6 @@
 		 return false;
 	 
 	 result &= r->deleteSWObject(object);
-	 
-	 /*
-	 if (object->getTypeInfo()->m_type == WorldObject::TypeInfo::TYPE_PLAYER)
-	 {
-		 DEBUG("Player deleted");
-		 m_players->erase(object->getId());
-	 }
-	 */
 	
 }
 
@@ -1025,7 +1017,7 @@
 		
 		// Debugging: Region, Koordinaten setzen
 		pl->getGridLocation()->m_region =0;
-		pl->getGeometry()->m_shape.m_coordinate_x = 8;
+		pl->getGeometry()->m_shape.m_coordinate_x = 12;
 		pl->getGeometry()->m_shape.m_coordinate_y = 8;
 		
 		insertPlayerIntoRegion(pl,pl->getGridLocation()->m_region);
@@ -1099,7 +1091,7 @@
 }
 
 
-void World::handleCommand(ClientCommand* comm, int slot)
+void World::handleCommand(ClientCommand* comm, int slot, float delay)
 {
 	DEBUG5("Kommando (%f %f) button: %i id: %i action: %i",comm->m_coordinate_x,comm->m_coordinate_y,comm->m_button, comm->m_id,comm->m_action);
 
@@ -1121,8 +1113,12 @@
 		// Kommando in den Puffer schreiben
 		comm->toString(&cv);
 		
+		/*
+		timeval tv;
+		gettimeofday(&tv, NULL);
+		DEBUG("timestamp %i system time %i",cv.getTimestamp(),tv.tv_usec/1000);
 
-
+		*/
 	 	// Datenpaket zum Server senden
 		getNetwork()->pushSlotMessage(cv.getBitStream());
 	}
@@ -1134,7 +1130,7 @@
 	}
 	else
 	{
-		pl->onClientCommand(comm);
+		pl->onClientCommand(comm,delay);
 	}
 	
 	
@@ -1159,7 +1155,7 @@
 {
 	// Timer weiterzaehlen und Limits feststellen
 	float timer_max[3];
-	timer_max[0] = 250; timer_max[2] = 500; timer_max[3] = 1000; 
+	timer_max[0] = 200; timer_max[2] = 500; timer_max[3] = 1000; 
 	for (int i=0; i<3; i++)
 	{
 		m_timer[i] += time;
@@ -1172,8 +1168,6 @@
 	}	
 	
 	
-	m_events->clear();
-	
 	DEBUG5("update %f",time);
 	for (int i=0;i<WORLD_MAX_REGIONS;i++)
 	{
@@ -1229,6 +1223,16 @@
 	
 	updatePlayers();
 	
+	m_events->clear();
+	
+	for (int i=0;i<WORLD_MAX_REGIONS;i++)
+	{
+		if (m_regions[i]!=0)
+		{
+			m_regions[i]->getEvents()->clear();
+		}
+	}
+	
 	m_network->update();
 	
 }
@@ -1239,11 +1243,30 @@
 	map<int,ServerWObject*>::iterator it;
 	Player* pl;
 	int slot;
-	for (it = m_player_slots->begin(); it != m_player_slots->end(); ++it)
+	for (it = m_player_slots->begin(); it != m_player_slots->end(); )
 	{
 		slot = it->first;
 		pl = static_cast<Player*>(it->second);
 		
+		if (m_server && slot != LOCAL_SLOT &&  
+				  (m_network->getSlotStatus( slot )!=NET_CONNECTED || pl->getState() == WorldObject::STATE_QUIT))
+		{
+			Event event;
+			event.m_type = Event::PLAYER_QUIT;
+			event.m_id = pl->getId();
+			
+			insertEvent(event);
+			
+			deleteSWObject(pl);
+			m_players->erase( pl->getId());
+			m_player_slots->erase(it++);
+			
+			DEBUG("player %i has quit",pl->getId());
+			
+			delete pl;
+			continue;
+		}
+		
 		if (pl->getState() == WorldObject::STATE_REGION_DATA_REQUEST)
 		{
 			DEBUG("send data request to server");
@@ -1280,43 +1303,44 @@
 			Packet* data;
 			CharConv* cv;
 			
-			if (m_network->getSlotStatus( slot )!=NET_CONNECTED)
+			
+			while (m_network->numberSlotMessages( slot )>0)
 			{
-				// disconnect
-			}
-			else
-			{
-				while (m_network->numberSlotMessages( slot )>0)
+				m_network->popSlotMessage( data ,slot);
+	
+				cv = new CharConv(data);
+
+				headerp.fromString(cv);
+				
+				if (headerp.m_content ==  PTYPE_C2S_COMMAND)
 				{
-					m_network->popSlotMessage( data ,slot);
-		
-					cv = new CharConv(data);
-
-					headerp.fromString(cv);
-					
-					if (headerp.m_content ==  PTYPE_C2S_COMMAND)
-					{
-						// Kommando Daten erhalten
-						ClientCommand com;
+					// Kommando Daten erhalten
+					ClientCommand com;
 
-						// Spielerobjekt die Daten senden
-						com.fromString(cv);	
-						
-						handleCommand(&com,slot);
-					}
+					// Spielerobjekt die Daten senden
+					com.fromString(cv);
+					
+					/*
+					timeval tv;
+					gettimeofday(&tv, NULL);
+					DEBUG("timestamp %i delay %i  system time %i",cv->getTimestamp(), cv->getDelay(),tv.tv_usec/1000);
+					*/
 					
-					if (headerp.m_content == PTYPE_C2S_DATA_REQUEST)
-					{
-						// Datenanfrage erhalten
-						ClientDataRequest req;
-						req.fromString(cv);
-							
-						handleDataRequest(&req,slot);
-					}
-					
-					delete cv;
+					handleCommand(&com,slot,cv->getDelay());
 				}
+				
+				if (headerp.m_content == PTYPE_C2S_DATA_REQUEST)
+				{
+					// Datenanfrage erhalten
+					ClientDataRequest req;
+					req.fromString(cv);
+						
+					handleDataRequest(&req,slot);
+				}
+				
+				delete cv;
 			}
+			
 		}
 		
 		if (m_server)
@@ -1334,6 +1358,7 @@
 			}
 		}
 		
+		++it;
 	}
 	
 	if (!m_server)
@@ -1434,9 +1459,13 @@
 				{
 					Region* reg = m_local_player->getRegion();
 					
+					bool ret;
 					for (int n=0; n< headerp.m_number;n++)
 					{
-						processEvent(reg,cv);
+						ret = processEvent(reg,cv);
+						
+						if (ret == false)
+							break;
 					}
 
 				}
@@ -1448,6 +1477,8 @@
 	}
 	
 	
+	
+
 	if (m_server)
 	{
 		// Nachrichten ueber die Events zur den Clients senden
@@ -1484,6 +1515,7 @@
 				// globale Events
 				for (lt = m_events->begin(); lt != m_events->end(); ++lt)
 				{
+					DEBUG5(" send global event %i id %i",lt->m_type,lt->m_id);
 					writeEvent(reg,&(*lt),&msg);
 				}
 				
@@ -1514,28 +1546,40 @@
 	
 	ServerWObject* object;
 	DmgProjectile* proj;
-	if (event->m_type == Event::OBJECT_CREATED)
-	{
-		object =region->getSWObject(event->m_id);
-		object->toString(cv);
-	}
-	
-	if (event->m_type == Event::OBJECT_STAT_CHANGED)
+	Item* item;
+	if (region !=0)
 	{
-		object =region->getSWObject(event->m_id);
-		object->writeEvent(event,cv);
-	}
-	
-	if (event->m_type == Event::PROJECTILE_CREATED)
-	{
-		proj = region->getProjectile(event->m_id);
-		proj->toString(cv);
-	}
-	
-	if (event->m_type == Event::PROJECTILE_STAT_CHANGED)
-	{
-		proj = region->getProjectile(event->m_id);
-		proj->writeEvent(event,cv);
+		if (event->m_type == Event::OBJECT_CREATED)
+		{
+			object =region->getSWObject(event->m_id);
+			object->toString(cv);
+		}
+		
+		if (event->m_type == Event::OBJECT_STAT_CHANGED)
+		{
+			
+			object =region->getSWObject(event->m_id);
+			object->writeEvent(event,cv);
+			
+		}
+		
+		if (event->m_type == Event::PROJECTILE_CREATED)
+		{
+			proj = region->getProjectile(event->m_id);
+			proj->toString(cv);
+		}
+		
+		if (event->m_type == Event::PROJECTILE_STAT_CHANGED)
+		{
+			proj = region->getProjectile(event->m_id);
+			proj->writeEvent(event,cv);
+		}
+		
+		if (event->m_type == Event::ITEM_DROPPED)
+		{
+			item = region->getItem(event->m_id);
+			item->toString(cv);
+		}
 	}
 	
 	if (event->m_type == Event::PLAYER_CHANGED_REGION)
@@ -1545,10 +1589,18 @@
 		cv->toBuffer(object->getGeometry()->m_shape.m_coordinate_y);
 				
 	}
+	
+	if (event->m_type == Event::PLAYER_ITEM_EQUIPED)
+	{
+		DEBUG("send event: player equiped item");
+		object = (*m_players)[event->m_id];
+		cv->toBuffer<short>((short) event->m_data);
+		static_cast<Player*>(object)->getEquipement()->getItem(event->m_data)->toString(cv);
+	}
 }
 
 
-void World::processEvent(Region* region,CharConv* cv)
+bool World::processEvent(Region* region,CharConv* cv)
 {
 	Event event;
 	event.fromString(cv);
@@ -1575,6 +1627,7 @@
 		{
 			// Event erhalten zu dem kein Objekt gehoert
 			DEBUG("object %i for event does not exist",event.m_id);
+			return false;
 		}
 	}
 	
@@ -1605,6 +1658,10 @@
 		{
 			proj->processEvent(&event,cv);
 		}
+		else
+		{
+			return false;
+		}
 	}
 	
 	if (event.m_type == Event::PROJECTILE_DESTROYED)
@@ -1634,6 +1691,72 @@
 			}
 		}
 	}
+	
+	if (event.m_type == Event::PLAYER_QUIT)
+	{
+		if (m_players->count(event.m_id)>0)
+		{
+			object = (*m_players)[event.m_id];
+			if (object != m_local_player)
+			{
+				deleteSWObject(object);
+				m_players->erase( object->getId());
+				
+				map<int,ServerWObject*>::iterator it;
+				for (it = m_player_slots->begin(); it != m_player_slots->end(); ++it)
+				{
+					if (it->second == object)
+					{
+						m_player_slots->erase(it);
+						break;
+					}
+
+				}
+				
+				delete object;
+			}
+		}
+	}
+	
+	if (event.m_type == Event::ITEM_DROPPED)
+	{
+		region->createItemFromString(cv,event.m_id);	
+	}
+	
+	if (event.m_type == Event::ITEM_REMOVED)
+	{
+		region->deleteItem(event.m_id);
+	}
+	
+	if (event.m_type == Event::PLAYER_NOITEM_EQUIPED)
+	{
+		if (m_players->count(event.m_id)>0)
+		{
+			object = (*m_players)[event.m_id];
+			if (object != m_local_player)
+			{
+				Item* item =0;
+				static_cast<Player*>(object)->getEquipement()->swapItem(item,event.m_data);
+				
+				if (item !=0)
+					delete item;
+			}
+		}
+	}
+	
+	if (event.m_type == Event::PLAYER_ITEM_EQUIPED)
+	{
+		if (m_players->count(event.m_id)>0)
+		{
+			object = (*m_players)[event.m_id];
+			if (object != m_local_player)
+			{
+				static_cast<Player*>(object)->readItem(cv);
+			}
+		}
+	}
+	
+	return true;
 }
 
 
@@ -1931,6 +2054,11 @@
 	}
 }
 
+void World::insertEvent(Event &event)
+{
+	
+	m_events->push_back(event);
+	
+}
 
 
-
--- a/src/core/world.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/world.h	Thu Sep 25 11:05:55 2008 +0000
@@ -22,6 +22,9 @@
 
 using namespace std;
 
+
+#include <sys/time.h>
+
 #include <string>
 #include <list>
 #include <map>
@@ -367,12 +370,12 @@
 	void writeEvent(Region* region, Event* event, CharConv* cv);
 	
 	/**
-	 * \fn void processEvent(CharConv* cv)
+	 * \fn bool processEvent(CharConv* cv)
 	 * \brief Liest ein Event aus dem Bitstream und fuehrt es aus
 	 * \param region Region in der das Event aufgetreten ist
 	 * \param cv Bitstream
 	 */
-	void processEvent(Region* region,CharConv* cv);
+	bool processEvent(Region* region,CharConv* cv);
 
 	/**
 	 * \fn void calcBlockArray(PathfindInfo* p)
@@ -467,8 +470,9 @@
 	 * \brief Behandelt ein erhaltenes Kommmando
 	 * \param cmd Kommando
 	 * \param slot Slot ueber den das Kommando empfangen wurde. Wenn das Kommando nicht ueber das Netzwerk uebertragen wurde -1
+	 * \param delay Millisekunden die das Kommando verspaetet erhalten wurde
 	 */
-	void handleCommand(ClientCommand* cmd, int slot=LOCAL_SLOT);
+	void handleCommand(ClientCommand* cmd, int slot=LOCAL_SLOT, float delay=0);
 	
 	/**
 	 * \fn void handleDataRequest(ClientDataRequest* request, int slot  = LOCAL_SLOT)
@@ -482,10 +486,7 @@
 	 * \fn void insertEvent(Event &event)
 	 * \brief Fuegt ein neues Event in die Eventliste ein
 	 */
-	void insertEvent(Event &event)
-	{
-		m_events->push_back(event);
-	}
+	void insertEvent(Event &event);
 	
 	/**
 	 * \fn bool isServer()
@@ -500,6 +501,8 @@
 	{
 		return m_timer_limit[i];
 	}
+	
+	
 			
 
 //Private stuff
--- a/src/core/worldobject.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/core/worldobject.h	Thu Sep 25 11:05:55 2008 +0000
@@ -317,7 +317,9 @@
 			STATE_REGION_DATA_REQUEST=6,
 			STATE_REGION_DATA_WAITING=4,
 			STATE_ENTER_REGION =5,
+			STATE_QUIT=9,
 			STATE_STATIC = 10,
+
 	};
 
 	/**
--- a/src/gl_gui/window_main_gl.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/gl_gui/window_main_gl.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -107,6 +107,12 @@
 
 void WindowMain::TimerFunc(int dummy)
 {
+	/*
+	timeval tv;
+	gettimeofday(&tv, NULL);
+	DEBUG("system time %i",tv.tv_usec/1000);
+	*/
+	
 	if (global_doc->getState() == Document::SHUTDOWN)
 		exit(0);
 	
--- a/src/gl_gui/window_main_gl.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/gl_gui/window_main_gl.h	Thu Sep 25 11:05:55 2008 +0000
@@ -1,6 +1,9 @@
 #ifndef WINMAIN_H
 #define WINMAIN_H
 
+
+#include <sys/time.h>
+
 class WindowMain
 {
 	public:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/config	Thu Sep 25 11:05:55 2008 +0000
@@ -0,0 +1,2 @@
+127.0.0.1
+134.109.114.56
\ No newline at end of file
--- a/src/gui/main_gui.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/gui/main_gui.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -29,10 +29,19 @@
 	#else
         save = "default.sav";
     #endif
+	
+	bool server = true;
+	if (argc>=3)
+	{
+		if (std::string(argv[2]) == "-c")
+		{
+			server = false;
+		}
+	}
 	Document* doc = app->getDocument();
 	doc->setSaveFile(save);
 	
-	doc->setServer(true);
+	doc->setServer(server);
 	doc->setState(Document::START_GAME);
 	doc->getGUIState()->m_sheet= Document::GAME_SCREEN;
 	doc->getGUIState()->m_shown_windows = Document::NO_WINDOWS;
--- a/src/gui/mainwindow.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/gui/mainwindow.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -65,6 +65,9 @@
 	m_window->getCustomAttribute("WINDOW", &hWnd);
 	// OIS mitteilen fuer welches Fenster die Eingaben abgefangen werden sollen
 	pl.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(hWnd)));
+	pl.insert( std::make_pair(std::string("x11_mouse_grab"), std::string("false") ) ); 
+	pl.insert( std::make_pair(std::string("x11_keyboard_grab"), std::string("false"))); 
+	
 	m_ois = OIS::InputManager::createInputSystem( pl );
 
 	// Maus initialisieren
@@ -3280,7 +3283,7 @@
 	unsigned int id = we.window->getID();
 	if (we.button == CEGUI::LeftButton)
 	{
-		DEBUG("left button released on Item %i",id);
+		DEBUG5("left button released on Item %i",id);
 	}
 
 }
--- a/src/gui/mainwindow.h	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/gui/mainwindow.h	Thu Sep 25 11:05:55 2008 +0000
@@ -347,7 +347,6 @@
 	 */
 	bool consumeEvent(const CEGUI::EventArgs& evt)
 	{
-		DEBUG("consumed");
 		m_gui_hit = true;
 		return true;
 	}
--- a/src/gui/scene.cpp	Mon Sep 22 13:35:41 2008 +0000
+++ b/src/gui/scene.cpp	Thu Sep 25 11:05:55 2008 +0000
@@ -201,6 +201,9 @@
 	
 	if (player ==0)
 		return;
+	if (player->getRegion() ==0)
+		return;
+	
 	// Nummer der region in der sich der Spieler befindet
 	short region_nr = player->getGridLocation()->m_region;
 	
@@ -210,13 +213,15 @@
 	if (region_nr != m_region_id)
 	{
 		// Spieler hat eine neue Region betreten
-		m_region_id = region_nr;
 		if (player->getState() == WorldObject::STATE_ACTIVE)
 		{
 			// Szene komplett neu aufbauen
 			createScene();
 
 			m_document->setModified(m_document->getModified() & ~Document::REGION_MODIFIED);
+			
+			m_region_id = region_nr;
+		
 		}
 		else
 		{
@@ -532,7 +537,7 @@
                 if (old_ent_name != jt->second)
                 {
                     // Es soll ein anderes Mesh angehaengt werden als aktuell angehaengt ist
-                    DEBUG("replaced mesh %s by %s at bone %s",old_ent_name.c_str(),jt->second.c_str(),bone.c_str());
+                    DEBUG5("replaced mesh %s by %s at bone %s",old_ent_name.c_str(),jt->second.c_str(),bone.c_str());
 
 
                     // altes Mesh entfernen, neues anhaengen
@@ -1082,6 +1087,8 @@
 	{
 		name = (*it)->getNameId();
 
+		DEBUG5("create static object %s",name.c_str());
+		
 		// Objekt in der Szene erzeugen
 		createObject((*it),name,true);