changeset 1964:f92c89a7725e

exit game now goes back to character selection
author wuha
date Wed, 26 Oct 2011 21:20:41 +0000
parents 35ea7c175523
children e6af8ac20c22
files src/core/document.cpp
diffstat 1 files changed, 1902 insertions(+), 1901 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/document.cpp	Wed Oct 26 21:07:11 2011 +0000
+++ b/src/core/document.cpp	Wed Oct 26 21:20:41 2011 +0000
@@ -1,790 +1,790 @@
-/*
- * 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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "fstream"
-#include "document.h"
-
-#include "sound.h"
-#include "music.h"
-
-#include "networkstruct.h"
-#include "projectile.h"
-#include "party.h"
-#include "debug.h"
-#include "damage.h"
-#include "itemlist.h"
-#include "random.h"
-#include "item.h"
-#include "matrix2d.h"
-#include "dropitem.h"
-#include "world.h"
-#include "player.h"
-#include "timer.h"
-#include "sumwarshelper.h"
-
-#include "gettext.h"
-#include "stdstreamconv.h"
-
-
-#include "CEGUI/CEGUI.h"
-
-#include <physfs.h>
-
-// Constructors/Destructors
-// Initialisiert Document zu Testzwecken
-Document::Document()
-{
-
-	// Informationen zu Aktionen initialisieren
-	Action::init();
-
-
-	// Status der GUI setzen
-	getGUIState()->m_left_mouse_pressed= false;
-	getGUIState()->m_right_mouse_pressed= false;
-	getGUIState()->m_middle_mouse_pressed= false;
-	getGUIState()->m_shift_hold = false;
-	getGUIState()->m_item_labels = false;
-	getGUIState()->m_sheet= MAIN_MENU;
-	getGUIState()->m_shown_windows = NO_WINDOWS;
-	//getGUIState()->m_pressed_key = OIS::KC_UNASSIGNED;
-	getGUIState()->m_pressed_key =0;
-	getGUIState()->m_cursor_object ="";
-	getGUIState()->m_cursor_object_id =0;
-	getGUIState()->m_cursor_item_id =0;
-	getGUIState()->m_right_mouse_pressed_time=0;
-	getGUIState()->m_left_mouse_pressed_time=0;
-	getGUIState()->m_hover_ability = "noaction";
-	getGUIState()->m_prefer_right_skill = false;
-
-	// Pointer/Inhalte mit 0 initialisieren
-	m_gui_state.m_chat_window_content = "";
-	m_options_timer.start();
-
-	// aktuell eingestellte Aktionen setzen
-
-	// Status setzen
-	m_state = INACTIVE;
-
-	m_modified =GUISHEET_MODIFIED | WINDOWS_MODIFIED;
-
-	m_temp_player = 0;
-	m_single_player = true;
-}
-
-void Document::startGame(bool server)
-{
-	m_server = server;
-
-	// momentan: alle Spiele sind kooperativ
-	int port = Options::getInstance()->getPort();
-	int max_players = Options::getInstance()->getMaxNumberPlayers();
-	std::string host = Options::getInstance()->getServerHost();
-
-	if (m_single_player)
-	{
-		max_players = 1;
-	}
-
-	World::createWorld(server,port, true,max_players);
-
-	if (server)
-	{
-
-
-
-	}
-	else
-	{
-		ClientNetwork* net = static_cast<ClientNetwork*>(World::getWorld()->getNetwork());
-		net->serverConnect((char*) host.c_str(),port);
-
-	}
-	m_state = LOAD_SAVEGAME;
-}
-
-void Document::setSaveFile(std::string s)
-{
-	std::string userPath = SumwarsHelper::userPath();
-	userPath.append("/save/").append(s);
-
-	std::fstream file(userPath.c_str(),std::ios::in| std::ios::binary);
-	if (file.is_open())
-	{
-		char bin;
-		unsigned char* data=0;
-		m_save_file = userPath;
-
-		DEBUG ("Loaded save file %s", s.c_str());
-
-		file.get(bin);
-
-		CharConv* save;
-		DEBUGX("binary %i",bin);
-		if (bin == '0')
-		{
-			save = new StdStreamConv(&file);
-		}
-		else
-		{
-			// binary savefile is not supported anymore
-			ERRORMSG("binary Savegame is not supported anymore");
-			return;
-		}
-
-		if (m_temp_player)
-			delete m_temp_player;
-
-		m_temp_player = new Player(0,"");
-		m_temp_player->fromSavegame(save);
-
-		delete save;
-		if (data)
-			delete[] data;
-
-
-	}
-	else
-	{
-		if (m_temp_player)
-		{
-			delete m_temp_player;
-			m_temp_player =0;
-		}
-		m_save_file ="";
-	}
-	m_modified |= SAVEGAME_MODIFIED;
-	file.close();
-}
-
-void Document::loadSavegame()
-{
-	// read savegame
-	std::string fname = m_save_file;
-	DEBUG("savegame is %s",fname.c_str());
-
-	std::fstream file(fname.c_str(),std::ios::in| std::ios::binary);
-	if (file.is_open())
-	{
-		char bin;
-		unsigned char* data=0;
-
-		file.get(bin);
-
-		CharConv* save;
-		// determine binary vs nonbinary savegile
-		if (bin == '0')
-		{
-			save = new StdStreamConv(&file);
-		}
-		else
-		{
-			// binary savefile is not supported anymore
-			ERRORMSG("binary Savegame is not supported anymore");
-			return;
-		}
-
-		// update the player object, that is displayed in character preview and inventory
-		if (m_temp_player)
-			delete m_temp_player;
-
-		m_temp_player = new Player(0,"");
-		m_temp_player->fromSavegame(save);
-
-		// notify the world of the new player
-
-		std::stringstream sstream;
-		StdStreamConv cv2(&sstream);
-
-		Timer t;
-		t.start();
-		while (t.getTime() < 200)
-		{
-		}
-
-		m_temp_player->toSavegame(&cv2);
-		DEBUG("sending savegame");
-		World::getWorld()->handleSavegame(&cv2);
-		DEBUGX("sent savegame");
-
-		// read shortkeys from the savegame
-		m_ability_shortkey_map.clear();
-		short key,dest;
-		int nr =0;
-		save->fromBuffer(nr);
-		for (int i=0; i<nr; ++i)
-		{
-			save->fromBuffer(key);
-			save->fromBuffer(dest);
-			if (dest >= USE_SKILL_LEFT && dest < USE_SKILL_RIGHT + 200)
-			{
-				installShortkey((KeyCode) key, (ShortkeyDestination) dest);
-			}
-		}
-
-		// update state to running
-		// show main game screen
-		m_state =RUNNING;
-		m_gui_state.m_shown_windows = NO_WINDOWS;
-		m_gui_state.m_sheet = GAME_SCREEN;
-		m_modified = WINDOWS_MODIFIED | GUISHEET_MODIFIED;
-		m_save_timer.start();
-
-		file.close();
-		if (data)
-			delete[] data;
-		delete save;
-	}
-	else
-	{
-		if (m_save_file == "")
-		{
-			// no save file chosen, go to character creation
-			getGUIState()->m_shown_windows =CHAR_CREATE;
-			m_modified = WINDOWS_MODIFIED | GUISHEET_MODIFIED ; 
-			m_gui_state.m_sheet = MAIN_MENU;
-			m_state = INACTIVE;
-		}
-		else
-		{
-			ERRORMSG("could not open savegame: %s", fname.c_str());
-			m_state =SHUTDOWN;
-		}
-	}
-	DEBUGX("done");
-}
-
-Document::~Document()
-{
-
-}
-// Methods
-
-void Document::onCreateNewCharButton()
-{
-	if (m_temp_player)
-	{
-		delete m_temp_player;
-		m_temp_player =0;
-	}
-
-	m_modified |= SAVEGAME_MODIFIED;
-
-	getGUIState()->m_shown_windows =CHAR_CREATE;
-	m_modified |= WINDOWS_MODIFIED;
-
-}
-
-
-void Document::setNewCharacter(WorldObject::Subtype subtype, PlayerLook look)
-{
-	if (m_temp_player)
-		delete m_temp_player;
-
-	m_temp_player = new Player(0,subtype);
-	m_temp_player->getPlayerLook() = look;
-
-	m_modified |= SAVEGAME_MODIFIED;
-}
-
-bool Document::createNewCharacter(std::string name)
-{
-	if (m_temp_player)
-	{
-
-        std::string path = PHYSFS_getUserDir();
-#ifndef __APPLE__
-		path.append("/.sumwars/save/");
-#else
-        path.append("/Library/Application Support/Sumwars/save/");
-#endif
-        m_save_file = path;
-		m_save_file += name;
-		m_save_file += ".sav";
-
-		m_temp_player ->setName(TranslatableString(name,""));
-
-		DEBUGX("savefile %s",m_save_file.c_str());
-
-		std::ifstream file(m_save_file.c_str());
-		if (file.is_open())
-		{
-			//ERRORMSG("file exists: %s",m_save_file.c_str());
-			return false;
-		}
-
-		writeSavegame(false);
-
-		getGUIState()->m_shown_windows = Document::START_MENU;
-		setModified(Document::WINDOWS_MODIFIED);
-	}
-	return true;
-}
-
-void Document::sendCommand(ClientCommand* comm)
-{
-	if (World::getWorld() != 0)
-	{
-		World::getWorld()->handleCommand(comm);
-	}
-}
-
-
-
-
-void Document::installShortkey(KeyCode key,ShortkeyDestination dest)
-{
-	Options* opt = Options::getInstance();
-	// do not use special keys nor overwrite global shortkeys
-	if (opt->isSpecialKey(key) || opt->getMappedKey(dest) != 0)
-		return;
-
-	// key that was mapped to the action dest so far
-	KeyCode oldkey = 0;
-	std::map<KeyCode, ShortkeyDestination>::iterator it;
-	for (it=m_ability_shortkey_map.begin(); it!= m_ability_shortkey_map.end();++it)
-	{
-		if (it->second == dest)
-		{
-			oldkey = it->first;
-			break;
-		}
-	}
-	// delete mapping
-	if (oldkey != 0)
-	{
-		m_ability_shortkey_map.erase(oldkey);
-	}
-
-	// create new mapping
-	m_ability_shortkey_map[key]=dest;
-}
-
-void Document::onButtonSendMessageClicked ( )
-{
-	DEBUGX("onbuttonmessageclicked");
-}
-
-
-void Document::onButtonSaveExitClicked ( )
-{
-	getGUIState()->m_shown_windows = SAVE_EXIT;
-	m_modified |= WINDOWS_MODIFIED;
-
-	if (m_state == INACTIVE)
-	{
-		saveSettings();
-		m_state = END_GAME;
-		return;
-	}
-}
-
-void Document::onButtonSaveExitConfirm()
-{
-
-
-	if (m_state!=SHUTDOWN_REQUEST)
-	{
-		setState(SHUTDOWN_REQUEST);
-	}
-	else
-	{
-		setState(SHUTDOWN);
-	}
-
-	m_shutdown_timer =0;
-
-	ClientCommand command;
-
-	// Paket mit Daten fuellen
-	// Button ist Speichern+Beenden, alle anderen Daten gleich 0
-	command.m_button=BUTTON_SAVE_QUIT;
-	command.m_goal = Vector(0,0);
-	command.m_id=0;
-	command.m_number=0;
-
-	// Paket an den Server senden
-	sendCommand(&command);
-
-	getGUIState()->m_shown_windows = NO_WINDOWS;
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-void Document::onButtonSaveExitAbort()
-{
-	getGUIState()->m_shown_windows = NO_WINDOWS;
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-void Document::onButtonCredits()
-{
-	getGUIState()->m_shown_windows =CREDITS;
-	m_modified =WINDOWS_MODIFIED;
-}
-
-void Document::onRightMouseButtonClick(Vector pos)
-{
-	ClientCommand command;
-
-	// der lokale Spieler
-	Player* pl = static_cast<Player*> (World::getWorld()->getLocalPlayer());
-	if (pl==0)
-		return;
-
-
-	// herstellen der Koordinaten im Koordinatensystem des Spiels
-	m_gui_state.m_clicked = pos;
-
-	// Paket mit Daten fuellen
-	command.m_button=RIGHT_MOUSE_BUTTON;
-	command.m_goal = m_gui_state.m_clicked;
-	command.m_action = pl->getRightAction();
-
-	m_gui_state.m_left_mouse_pressed=false;
-	m_gui_state.m_right_mouse_pressed_time=0;
-
-	DEBUGX("angeklickte Koordinaten: %f %f",pos.m_x,pos.m_y);
-
-	m_gui_state.m_clicked_object_id=0;
-	command.m_id=0;
-
-	int id = 0;
-	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;
-
-	command.m_number=0;
-
-	if (command.m_id != 0)
-	{
-		DEBUGX ("Clicked object %i",command.m_id);
-	}
-
-
-	// Paket an den Server senden
-	sendCommand(&command);
-
-}
-
-void Document::onLeftMouseButtonClick(Vector pos)
-{
-
-	ClientCommand command;
-
-	// der lokale Spieler
-	Player* pl = static_cast<Player*> (World::getWorld()->getLocalPlayer());
-	if (pl==0)
-		return;
-
-	// Dialog is open, each klick is interpreted as *skip this text*
-	if (pl->getDialogueId() != 0)
-	{
-		onSkipDialogueTextClicked();
-		return;
-	}
-
-	// herstellen der Koordinaten im Koordinatensystem des Spiels
-
-	m_gui_state.m_clicked = pos;
-
-
-	// Paket mit Daten fuellen
-	command.m_button=LEFT_MOUSE_BUTTON;
-	if (m_gui_state.m_shift_hold)
-	{
-		command.m_button=LEFT_SHIFT_MOUSE_BUTTON;
-	}
-	command.m_goal = m_gui_state.m_clicked;
-	command.m_action = pl->getLeftAction();
-
-	m_gui_state.m_right_mouse_pressed=false;
-	m_gui_state.m_left_mouse_pressed_time=0;
-
-
-	DEBUGX("angeklickte Koordinaten: %f %f",pos.m_x,pos.m_y);
-
-	m_gui_state.m_clicked_object_id=0;
-	command.m_id=0;
-
-
-	int id = 0;
-	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;
-	command.m_number=0;
-
-	// Linksklick auf die eigene Figur unnoetig
-	if (command.m_id == getLocalPlayer()->getId())
-	{
-		command.m_id=0;
-	}
-
-	if (command.m_id!=0)
-	{
-		DEBUGX("angeklicktes Objekt %i",command.m_id);
-	}
-
-	if (command.m_id ==0 && m_gui_state.m_cursor_item_id!=0)
-	{
-		// Item angeklickt
-		command.m_action = "take_item";
-		command.m_id = m_gui_state.m_cursor_item_id;
-
-		DEBUGX("clicked at item %i",m_gui_state.m_cursor_item_id);
-	}
-
-	// Paket an den Server senden
-	sendCommand(&command);
-
-
-}
-
-void Document::onMouseMove(float xrel, float yrel, float wheelrel)
-{
-	Player* player = getLocalPlayer();
-	if (player!=0)
-	{
-		if (! getGUIState()->m_middle_mouse_pressed)
-		{
-			xrel= yrel =0;
-		}
-		player->getCamera().moveRelative(wheelrel*0.01,yrel*0.5,-xrel*0.5);
-	}
-}
-
-void Document::onStartScreenClicked()
-{
-	if (getGUIState()->m_shown_windows == NO_WINDOWS)
-	{
-		//getGUIState()->m_shown_windows = SAVEGAME_LIST;
-		getGUIState()->m_shown_windows = START_MENU;
-		m_modified =WINDOWS_MODIFIED;
-	}
-
-	if (getGUIState()->m_shown_windows == CREDITS)
-	{
-		getGUIState()->m_shown_windows = START_MENU;
-		m_modified =WINDOWS_MODIFIED;
-	}
-}
-
-int Document::getObjectAt(float x,float y)
-{
-	// der lokale Spieler
-	WorldObject* pl = World::getWorld()->getLocalPlayer();
-	if (pl==0)
-		return 0;
-
-	// Region in der sich der lokale Spieler befindet
-	Region* reg = pl->getRegion();
-	if (reg ==0)
-		return 0;
-
-	WorldObject* obj = reg->getObjectAt(Vector(x,y));
-	if (obj != 0)
-		return obj->getId();
-
-	return 0;
-
-}
-
-
-void Document::onButtonPartyApply(int id)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_APPLY;
-	command.m_id = id;
-	sendCommand(&command);
-}
-
-void Document::onButtonPartyAccept(int id)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_MEMBER_ACCEPT;
-	command.m_id = id;
-	sendCommand(&command);
-
-}
-
-void Document::onButtonPartyReject(int id)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_MEMBER_REJECT;
-	command.m_id = id;
-	sendCommand(&command);
-
-}
-
-void Document::onButtonPartyWar(int id)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_WAR;
-	command.m_id = id;
-	sendCommand(&command);
-
-}
-
-void Document::onButtonPartyPeace(int id)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_PEACE;
-	command.m_id = id;
-	sendCommand(&command);
-
-}
-
-
-void Document::onButtonKick(int id)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_KICK;
-	command.m_id = id;
-	sendCommand(&command);
-}
-
-void Document::onButtonPartyLeave()
-{
-	ClientCommand command;
-	command.m_button = BUTTON_LEAVE;
-	sendCommand(&command);
-}
-
-void Document::onItemLeftClick(short pos)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_ITEM_LEFT;
-	command.m_id = pos;
-	sendCommand(&command);
-
-}
-
-void Document::onItemRightClick(short pos)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_ITEM_RIGHT;
-	command.m_id = pos;
-	sendCommand(&command);
-
-}
-
-void Document::onTradeItemLeftClick(short pos)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_TRADE_ITEM_LEFT;
-	command.m_id = pos;
-	sendCommand(&command);
-
-}
-
-void Document::onTradeItemRightClick(short pos)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_TRADE_ITEM_RIGHT;
-	command.m_id = pos;
-	sendCommand(&command);
-
-}
-
-void Document::onTradeSellClicked()
-{
-	ClientCommand command;
-	command.m_button = BUTTON_TRADE_SELL;
-	command.m_id = 0;
-	sendCommand(&command);
-}
-
-void Document::increaseAttribute(CreatureBaseAttr::Attribute attr)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_INCREASE_ATTRIBUTE;
-	command.m_id = attr;
-	DEBUGX("increasing attribute %i",attr);
-	sendCommand(&command);
-}
-
-void Document::learnAbility(Action::ActionType act)
-{
-	ClientCommand command;
-	command.m_button = BUTTON_LEARN_ABILITY;
-	command.m_action = act;
-	sendCommand(&command);
-}
-
-void Document::dropCursorItem()
-{
-	ClientCommand command;
-	command.m_button = DROP_ITEM;
-	command.m_id =0;
-	command.m_number =0;
-	sendCommand(&command);
-}
-
-void Document::dropGold(int value)
-{
-	ClientCommand command;
-	command.m_button = DROP_ITEM;
-	command.m_id =1;
-	command.m_number =value;
-	sendCommand(&command);
-}
-
-void Document::onDropItemClick(int id)
-{
-	ClientCommand command;
-	command.m_button=LEFT_MOUSE_BUTTON;
-	command.m_action = "take_item";
-	command.m_id = id;
-
-	// Paket an den Server senden
-	sendCommand(&command);
-}
-
-void Document::onAnswerClick(int id)
-{
-	ClientCommand command;
-	command.m_button=BUTTON_ANSWER;
-	command.m_action = "speak_answer";
-	command.m_id = id;
-
-	// Paket an den Server senden
-	sendCommand(&command);
-}
-
-
-void Document::emitDebugSignal(int i)
-{
-	ClientCommand command;
-	command.m_button = DEBUG_SIGNAL;
-	command.m_id = i;
-	sendCommand(&command);
-}
-
-bool Document::checkSubwindowsAllowed()
-{
-	bool ok = true;
-	ok &= (getState() == RUNNING || getState() == SHUTDOWN_REQUEST);
-	ok &= (getGUIState()->m_shown_windows & SAVE_EXIT) == 0;
-	ok &= (getGUIState()->m_shown_windows & (QUESTIONBOX | TRADE)) == 0;
+/*
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "fstream"
+#include "document.h"
+
+#include "sound.h"
+#include "music.h"
+
+#include "networkstruct.h"
+#include "projectile.h"
+#include "party.h"
+#include "debug.h"
+#include "damage.h"
+#include "itemlist.h"
+#include "random.h"
+#include "item.h"
+#include "matrix2d.h"
+#include "dropitem.h"
+#include "world.h"
+#include "player.h"
+#include "timer.h"
+#include "sumwarshelper.h"
+
+#include "gettext.h"
+#include "stdstreamconv.h"
+
+
+#include "CEGUI/CEGUI.h"
+
+#include <physfs.h>
+
+// Constructors/Destructors
+// Initialisiert Document zu Testzwecken
+Document::Document()
+{
+
+	// Informationen zu Aktionen initialisieren
+	Action::init();
+
+
+	// Status der GUI setzen
+	getGUIState()->m_left_mouse_pressed= false;
+	getGUIState()->m_right_mouse_pressed= false;
+	getGUIState()->m_middle_mouse_pressed= false;
+	getGUIState()->m_shift_hold = false;
+	getGUIState()->m_item_labels = false;
+	getGUIState()->m_sheet= MAIN_MENU;
+	getGUIState()->m_shown_windows = NO_WINDOWS;
+	//getGUIState()->m_pressed_key = OIS::KC_UNASSIGNED;
+	getGUIState()->m_pressed_key =0;
+	getGUIState()->m_cursor_object ="";
+	getGUIState()->m_cursor_object_id =0;
+	getGUIState()->m_cursor_item_id =0;
+	getGUIState()->m_right_mouse_pressed_time=0;
+	getGUIState()->m_left_mouse_pressed_time=0;
+	getGUIState()->m_hover_ability = "noaction";
+	getGUIState()->m_prefer_right_skill = false;
+
+	// Pointer/Inhalte mit 0 initialisieren
+	m_gui_state.m_chat_window_content = "";
+	m_options_timer.start();
+
+	// aktuell eingestellte Aktionen setzen
+
+	// Status setzen
+	m_state = INACTIVE;
+
+	m_modified =GUISHEET_MODIFIED | WINDOWS_MODIFIED;
+
+	m_temp_player = 0;
+	m_single_player = true;
+}
+
+void Document::startGame(bool server)
+{
+	m_server = server;
+
+	// momentan: alle Spiele sind kooperativ
+	int port = Options::getInstance()->getPort();
+	int max_players = Options::getInstance()->getMaxNumberPlayers();
+	std::string host = Options::getInstance()->getServerHost();
+
+	if (m_single_player)
+	{
+		max_players = 1;
+	}
+
+	World::createWorld(server,port, true,max_players);
+
+	if (server)
+	{
+
+
+
+	}
+	else
+	{
+		ClientNetwork* net = static_cast<ClientNetwork*>(World::getWorld()->getNetwork());
+		net->serverConnect((char*) host.c_str(),port);
+
+	}
+	m_state = LOAD_SAVEGAME;
+}
+
+void Document::setSaveFile(std::string s)
+{
+	std::string userPath = SumwarsHelper::userPath();
+	userPath.append("/save/").append(s);
+
+	std::fstream file(userPath.c_str(),std::ios::in| std::ios::binary);
+	if (file.is_open())
+	{
+		char bin;
+		unsigned char* data=0;
+		m_save_file = userPath;
+
+		DEBUG ("Loaded save file %s", s.c_str());
+
+		file.get(bin);
+
+		CharConv* save;
+		DEBUGX("binary %i",bin);
+		if (bin == '0')
+		{
+			save = new StdStreamConv(&file);
+		}
+		else
+		{
+			// binary savefile is not supported anymore
+			ERRORMSG("binary Savegame is not supported anymore");
+			return;
+		}
+
+		if (m_temp_player)
+			delete m_temp_player;
+
+		m_temp_player = new Player(0,"");
+		m_temp_player->fromSavegame(save);
+
+		delete save;
+		if (data)
+			delete[] data;
+
+
+	}
+	else
+	{
+		if (m_temp_player)
+		{
+			delete m_temp_player;
+			m_temp_player =0;
+		}
+		m_save_file ="";
+	}
+	m_modified |= SAVEGAME_MODIFIED;
+	file.close();
+}
+
+void Document::loadSavegame()
+{
+	// read savegame
+	std::string fname = m_save_file;
+	DEBUG("savegame is %s",fname.c_str());
+
+	std::fstream file(fname.c_str(),std::ios::in| std::ios::binary);
+	if (file.is_open())
+	{
+		char bin;
+		unsigned char* data=0;
+
+		file.get(bin);
+
+		CharConv* save;
+		// determine binary vs nonbinary savegile
+		if (bin == '0')
+		{
+			save = new StdStreamConv(&file);
+		}
+		else
+		{
+			// binary savefile is not supported anymore
+			ERRORMSG("binary Savegame is not supported anymore");
+			return;
+		}
+
+		// update the player object, that is displayed in character preview and inventory
+		if (m_temp_player)
+			delete m_temp_player;
+
+		m_temp_player = new Player(0,"");
+		m_temp_player->fromSavegame(save);
+
+		// notify the world of the new player
+
+		std::stringstream sstream;
+		StdStreamConv cv2(&sstream);
+
+		Timer t;
+		t.start();
+		while (t.getTime() < 200)
+		{
+		}
+
+		m_temp_player->toSavegame(&cv2);
+		DEBUG("sending savegame");
+		World::getWorld()->handleSavegame(&cv2);
+		DEBUGX("sent savegame");
+
+		// read shortkeys from the savegame
+		m_ability_shortkey_map.clear();
+		short key,dest;
+		int nr =0;
+		save->fromBuffer(nr);
+		for (int i=0; i<nr; ++i)
+		{
+			save->fromBuffer(key);
+			save->fromBuffer(dest);
+			if (dest >= USE_SKILL_LEFT && dest < USE_SKILL_RIGHT + 200)
+			{
+				installShortkey((KeyCode) key, (ShortkeyDestination) dest);
+			}
+		}
+
+		// update state to running
+		// show main game screen
+		m_state =RUNNING;
+		m_gui_state.m_shown_windows = NO_WINDOWS;
+		m_gui_state.m_sheet = GAME_SCREEN;
+		m_modified = WINDOWS_MODIFIED | GUISHEET_MODIFIED;
+		m_save_timer.start();
+
+		file.close();
+		if (data)
+			delete[] data;
+		delete save;
+	}
+	else
+	{
+		if (m_save_file == "")
+		{
+			// no save file chosen, go to character creation
+			getGUIState()->m_shown_windows =CHAR_CREATE;
+			m_modified = WINDOWS_MODIFIED | GUISHEET_MODIFIED ; 
+			m_gui_state.m_sheet = MAIN_MENU;
+			m_state = INACTIVE;
+		}
+		else
+		{
+			ERRORMSG("could not open savegame: %s", fname.c_str());
+			m_state =SHUTDOWN;
+		}
+	}
+	DEBUGX("done");
+}
+
+Document::~Document()
+{
+
+}
+// Methods
+
+void Document::onCreateNewCharButton()
+{
+	if (m_temp_player)
+	{
+		delete m_temp_player;
+		m_temp_player =0;
+	}
+
+	m_modified |= SAVEGAME_MODIFIED;
+
+	getGUIState()->m_shown_windows =CHAR_CREATE;
+	m_modified |= WINDOWS_MODIFIED;
+
+}
+
+
+void Document::setNewCharacter(WorldObject::Subtype subtype, PlayerLook look)
+{
+	if (m_temp_player)
+		delete m_temp_player;
+
+	m_temp_player = new Player(0,subtype);
+	m_temp_player->getPlayerLook() = look;
+
+	m_modified |= SAVEGAME_MODIFIED;
+}
+
+bool Document::createNewCharacter(std::string name)
+{
+	if (m_temp_player)
+	{
+
+        std::string path = PHYSFS_getUserDir();
+#ifndef __APPLE__
+		path.append("/.sumwars/save/");
+#else
+        path.append("/Library/Application Support/Sumwars/save/");
+#endif
+        m_save_file = path;
+		m_save_file += name;
+		m_save_file += ".sav";
+
+		m_temp_player ->setName(TranslatableString(name,""));
+
+		DEBUGX("savefile %s",m_save_file.c_str());
+
+		std::ifstream file(m_save_file.c_str());
+		if (file.is_open())
+		{
+			//ERRORMSG("file exists: %s",m_save_file.c_str());
+			return false;
+		}
+
+		writeSavegame(false);
+
+		getGUIState()->m_shown_windows = Document::START_MENU;
+		setModified(Document::WINDOWS_MODIFIED);
+	}
+	return true;
+}
+
+void Document::sendCommand(ClientCommand* comm)
+{
+	if (World::getWorld() != 0)
+	{
+		World::getWorld()->handleCommand(comm);
+	}
+}
+
+
+
+
+void Document::installShortkey(KeyCode key,ShortkeyDestination dest)
+{
+	Options* opt = Options::getInstance();
+	// do not use special keys nor overwrite global shortkeys
+	if (opt->isSpecialKey(key) || opt->getMappedKey(dest) != 0)
+		return;
+
+	// key that was mapped to the action dest so far
+	KeyCode oldkey = 0;
+	std::map<KeyCode, ShortkeyDestination>::iterator it;
+	for (it=m_ability_shortkey_map.begin(); it!= m_ability_shortkey_map.end();++it)
+	{
+		if (it->second == dest)
+		{
+			oldkey = it->first;
+			break;
+		}
+	}
+	// delete mapping
+	if (oldkey != 0)
+	{
+		m_ability_shortkey_map.erase(oldkey);
+	}
+
+	// create new mapping
+	m_ability_shortkey_map[key]=dest;
+}
+
+void Document::onButtonSendMessageClicked ( )
+{
+	DEBUGX("onbuttonmessageclicked");
+}
+
+
+void Document::onButtonSaveExitClicked ( )
+{
+	getGUIState()->m_shown_windows = SAVE_EXIT;
+	m_modified |= WINDOWS_MODIFIED;
+
+	if (m_state == INACTIVE)
+	{
+		saveSettings();
+		m_state = END_GAME;
+		return;
+	}
+}
+
+void Document::onButtonSaveExitConfirm()
+{
+
+
+	if (m_state!=SHUTDOWN_REQUEST)
+	{
+		setState(SHUTDOWN_REQUEST);
+	}
+	else
+	{
+		setState(SHUTDOWN);
+	}
+
+	m_shutdown_timer =0;
+
+	ClientCommand command;
+
+	// Paket mit Daten fuellen
+	// Button ist Speichern+Beenden, alle anderen Daten gleich 0
+	command.m_button=BUTTON_SAVE_QUIT;
+	command.m_goal = Vector(0,0);
+	command.m_id=0;
+	command.m_number=0;
+
+	// Paket an den Server senden
+	sendCommand(&command);
+
+	getGUIState()->m_shown_windows = NO_WINDOWS;
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+void Document::onButtonSaveExitAbort()
+{
+	getGUIState()->m_shown_windows = NO_WINDOWS;
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+void Document::onButtonCredits()
+{
+	getGUIState()->m_shown_windows =CREDITS;
+	m_modified =WINDOWS_MODIFIED;
+}
+
+void Document::onRightMouseButtonClick(Vector pos)
+{
+	ClientCommand command;
+
+	// der lokale Spieler
+	Player* pl = static_cast<Player*> (World::getWorld()->getLocalPlayer());
+	if (pl==0)
+		return;
+
+
+	// herstellen der Koordinaten im Koordinatensystem des Spiels
+	m_gui_state.m_clicked = pos;
+
+	// Paket mit Daten fuellen
+	command.m_button=RIGHT_MOUSE_BUTTON;
+	command.m_goal = m_gui_state.m_clicked;
+	command.m_action = pl->getRightAction();
+
+	m_gui_state.m_left_mouse_pressed=false;
+	m_gui_state.m_right_mouse_pressed_time=0;
+
+	DEBUGX("angeklickte Koordinaten: %f %f",pos.m_x,pos.m_y);
+
+	m_gui_state.m_clicked_object_id=0;
+	command.m_id=0;
+
+	int id = 0;
+	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;
+
+	command.m_number=0;
+
+	if (command.m_id != 0)
+	{
+		DEBUGX ("Clicked object %i",command.m_id);
+	}
+
+
+	// Paket an den Server senden
+	sendCommand(&command);
+
+}
+
+void Document::onLeftMouseButtonClick(Vector pos)
+{
+
+	ClientCommand command;
+
+	// der lokale Spieler
+	Player* pl = static_cast<Player*> (World::getWorld()->getLocalPlayer());
+	if (pl==0)
+		return;
+
+	// Dialog is open, each klick is interpreted as *skip this text*
+	if (pl->getDialogueId() != 0)
+	{
+		onSkipDialogueTextClicked();
+		return;
+	}
+
+	// herstellen der Koordinaten im Koordinatensystem des Spiels
+
+	m_gui_state.m_clicked = pos;
+
+
+	// Paket mit Daten fuellen
+	command.m_button=LEFT_MOUSE_BUTTON;
+	if (m_gui_state.m_shift_hold)
+	{
+		command.m_button=LEFT_SHIFT_MOUSE_BUTTON;
+	}
+	command.m_goal = m_gui_state.m_clicked;
+	command.m_action = pl->getLeftAction();
+
+	m_gui_state.m_right_mouse_pressed=false;
+	m_gui_state.m_left_mouse_pressed_time=0;
+
+
+	DEBUGX("angeklickte Koordinaten: %f %f",pos.m_x,pos.m_y);
+
+	m_gui_state.m_clicked_object_id=0;
+	command.m_id=0;
+
+
+	int id = 0;
+	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;
+	command.m_number=0;
+
+	// Linksklick auf die eigene Figur unnoetig
+	if (command.m_id == getLocalPlayer()->getId())
+	{
+		command.m_id=0;
+	}
+
+	if (command.m_id!=0)
+	{
+		DEBUGX("angeklicktes Objekt %i",command.m_id);
+	}
+
+	if (command.m_id ==0 && m_gui_state.m_cursor_item_id!=0)
+	{
+		// Item angeklickt
+		command.m_action = "take_item";
+		command.m_id = m_gui_state.m_cursor_item_id;
+
+		DEBUGX("clicked at item %i",m_gui_state.m_cursor_item_id);
+	}
+
+	// Paket an den Server senden
+	sendCommand(&command);
+
+
+}
+
+void Document::onMouseMove(float xrel, float yrel, float wheelrel)
+{
+	Player* player = getLocalPlayer();
+	if (player!=0)
+	{
+		if (! getGUIState()->m_middle_mouse_pressed)
+		{
+			xrel= yrel =0;
+		}
+		player->getCamera().moveRelative(wheelrel*0.01,yrel*0.5,-xrel*0.5);
+	}
+}
+
+void Document::onStartScreenClicked()
+{
+	if (getGUIState()->m_shown_windows == NO_WINDOWS)
+	{
+		//getGUIState()->m_shown_windows = SAVEGAME_LIST;
+		getGUIState()->m_shown_windows = START_MENU;
+		m_modified =WINDOWS_MODIFIED;
+	}
+
+	if (getGUIState()->m_shown_windows == CREDITS)
+	{
+		getGUIState()->m_shown_windows = START_MENU;
+		m_modified =WINDOWS_MODIFIED;
+	}
+}
+
+int Document::getObjectAt(float x,float y)
+{
+	// der lokale Spieler
+	WorldObject* pl = World::getWorld()->getLocalPlayer();
+	if (pl==0)
+		return 0;
+
+	// Region in der sich der lokale Spieler befindet
+	Region* reg = pl->getRegion();
+	if (reg ==0)
+		return 0;
+
+	WorldObject* obj = reg->getObjectAt(Vector(x,y));
+	if (obj != 0)
+		return obj->getId();
+
+	return 0;
+
+}
+
+
+void Document::onButtonPartyApply(int id)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_APPLY;
+	command.m_id = id;
+	sendCommand(&command);
+}
+
+void Document::onButtonPartyAccept(int id)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_MEMBER_ACCEPT;
+	command.m_id = id;
+	sendCommand(&command);
+
+}
+
+void Document::onButtonPartyReject(int id)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_MEMBER_REJECT;
+	command.m_id = id;
+	sendCommand(&command);
+
+}
+
+void Document::onButtonPartyWar(int id)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_WAR;
+	command.m_id = id;
+	sendCommand(&command);
+
+}
+
+void Document::onButtonPartyPeace(int id)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_PEACE;
+	command.m_id = id;
+	sendCommand(&command);
+
+}
+
+
+void Document::onButtonKick(int id)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_KICK;
+	command.m_id = id;
+	sendCommand(&command);
+}
+
+void Document::onButtonPartyLeave()
+{
+	ClientCommand command;
+	command.m_button = BUTTON_LEAVE;
+	sendCommand(&command);
+}
+
+void Document::onItemLeftClick(short pos)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_ITEM_LEFT;
+	command.m_id = pos;
+	sendCommand(&command);
+
+}
+
+void Document::onItemRightClick(short pos)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_ITEM_RIGHT;
+	command.m_id = pos;
+	sendCommand(&command);
+
+}
+
+void Document::onTradeItemLeftClick(short pos)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_TRADE_ITEM_LEFT;
+	command.m_id = pos;
+	sendCommand(&command);
+
+}
+
+void Document::onTradeItemRightClick(short pos)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_TRADE_ITEM_RIGHT;
+	command.m_id = pos;
+	sendCommand(&command);
+
+}
+
+void Document::onTradeSellClicked()
+{
+	ClientCommand command;
+	command.m_button = BUTTON_TRADE_SELL;
+	command.m_id = 0;
+	sendCommand(&command);
+}
+
+void Document::increaseAttribute(CreatureBaseAttr::Attribute attr)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_INCREASE_ATTRIBUTE;
+	command.m_id = attr;
+	DEBUGX("increasing attribute %i",attr);
+	sendCommand(&command);
+}
+
+void Document::learnAbility(Action::ActionType act)
+{
+	ClientCommand command;
+	command.m_button = BUTTON_LEARN_ABILITY;
+	command.m_action = act;
+	sendCommand(&command);
+}
+
+void Document::dropCursorItem()
+{
+	ClientCommand command;
+	command.m_button = DROP_ITEM;
+	command.m_id =0;
+	command.m_number =0;
+	sendCommand(&command);
+}
+
+void Document::dropGold(int value)
+{
+	ClientCommand command;
+	command.m_button = DROP_ITEM;
+	command.m_id =1;
+	command.m_number =value;
+	sendCommand(&command);
+}
+
+void Document::onDropItemClick(int id)
+{
+	ClientCommand command;
+	command.m_button=LEFT_MOUSE_BUTTON;
+	command.m_action = "take_item";
+	command.m_id = id;
+
+	// Paket an den Server senden
+	sendCommand(&command);
+}
+
+void Document::onAnswerClick(int id)
+{
+	ClientCommand command;
+	command.m_button=BUTTON_ANSWER;
+	command.m_action = "speak_answer";
+	command.m_id = id;
+
+	// Paket an den Server senden
+	sendCommand(&command);
+}
+
+
+void Document::emitDebugSignal(int i)
+{
+	ClientCommand command;
+	command.m_button = DEBUG_SIGNAL;
+	command.m_id = i;
+	sendCommand(&command);
+}
+
+bool Document::checkSubwindowsAllowed()
+{
+	bool ok = true;
+	ok &= (getState() == RUNNING || getState() == SHUTDOWN_REQUEST);
+	ok &= (getGUIState()->m_shown_windows & SAVE_EXIT) == 0;
+	ok &= (getGUIState()->m_shown_windows & (QUESTIONBOX | TRADE)) == 0;
 
 	// Also check to see if the current player is involved in anything that doesn't allow 
 	if (getLocalPlayer() != 0)
@@ -803,1117 +803,1118 @@
 			}
 		}
 	}
-	return ok;
-}
-
-
-
-void Document::onButtonStartSinglePlayer ()
-{
-	// The player is a host himself (or herself)
-	setServer (true);
-	m_single_player = true;
-
-	// Set the state and allow the connection to be established.
-	setState (Document::START_GAME);
-}
-
-
-
-void Document::onButtonHostGame()
-{
-	DEBUG("Host Game");
-	if (m_save_file == "")
-	{
-		// Show a notification.
-		CEGUI::WindowManager& win_mgr = CEGUI::WindowManager::getSingleton();
-		CEGUI::FrameWindow* message = (CEGUI::FrameWindow*) win_mgr.getWindow("WarningDialogWindow");
-		message->setInheritsAlpha(false);
-		message->setVisible(true);
-		message->setModalState(true);
-		win_mgr.getWindow( "WarningDialogLabel")->setText((CEGUI::utf8*) gettext("Please select a character first!"));
-
-		DEBUG ("Warning: Tried to host a game without a selected char!");
-		return;
-	}
-	getGUIState()->m_shown_windows |= HOST_GAME;
-	getGUIState()->m_shown_windows &= ~START_MENU;
-
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-void Document::onButtonJoinGame()
-{
-	if (m_save_file == "")
-	{
-		// Show a notification.
-		CEGUI::WindowManager& win_mgr = CEGUI::WindowManager::getSingleton();
-		CEGUI::FrameWindow* message = (CEGUI::FrameWindow*) win_mgr.getWindow("WarningDialogWindow");
-		message->setInheritsAlpha(false);
-		message->setVisible(true);
-		message->setModalState(true);
-		win_mgr.getWindow( "WarningDialogLabel")->setText((CEGUI::utf8*) gettext("Please select a character first!"));
-
-		DEBUG ("Warning: Tried to join a game without a selected char!");
-		return;
-	}
-	getGUIState()->m_shown_windows |= JOIN_GAME;
-	getGUIState()->m_shown_windows &= ~START_MENU;
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-void Document::onButtonStartHostGame()
-{
-	DEBUG("start multiplayer game");
-	// Spieler ist selbst der Host
-	setServer(true);
-	m_single_player = false;
-
-	// Verbindung aufbauen
-	setState(Document::START_GAME);
-}
-
-
-
-void Document::onButtonStartJoinGame()
-{
-	setServer(false);
-	m_single_player = false;
-	
-	// starten
-	setState(Document::START_GAME);
-}
-
-void Document::onButtonInventoryClicked()
-{
-	if (!checkSubwindowsAllowed())
-		return;
-
-	// Inventar oeffnen wenn es gerade geschlossen ist und schliessen, wenn es geoeffnet ist
-	if (getGUIState()->m_shown_windows & INVENTORY)
-	{
-
-		getGUIState()->m_shown_windows &= ~INVENTORY;
-
-		// der lokale Spieler
-		Player* pl = static_cast<Player*>( World::getWorld()->getLocalPlayer());
-		if (pl==0)
-			return;
-
-		// Item das aktuell in der Hand ist fallen lassen
-		if (pl->getEquipement()->getItem(Equipement::CURSOR_ITEM)!=0)
-		{
-			dropCursorItem();
-		}
-	}
-	else
-	{
-		// wenn Inventar geoeffnet wird, dann Skilltree schliessen
-		getGUIState()->m_shown_windows &= ~SKILLTREE;
-		m_gui_state.m_pressed_key = 0;
-
-		getGUIState()->m_shown_windows |= INVENTORY;
-
-
-
-	}
-
-	// Geoeffnete Fenster haben sich geaendert
-	m_modified |= WINDOWS_MODIFIED;
-
-}
-
-void Document::onButtonCharInfoClicked()
-{
-	if (!checkSubwindowsAllowed())
-		return;
-
-	// Charakterinfo oeffnen wenn es gerade geschlossen ist und schliessen, wenn es geoeffnet ist
-	if (getGUIState()->m_shown_windows & CHARINFO)
-	{
-		getGUIState()->m_shown_windows &= ~CHARINFO;
-	}
-	else
-	{
-		getGUIState()->m_shown_windows &= ~(PARTY | QUEST_INFO);
-
-		getGUIState()->m_shown_windows |= CHARINFO;
-	}
-
-	// Geoeffnete Fenster haben sich geaendert
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-void Document::onButtonPartyInfoClicked()
-{
-	if (!checkSubwindowsAllowed())
-		return;
-
-	// PartyInfo oeffnen wenn es gerade geschlossen ist und schliessen, wenn er geoeffnet ist
-	if (getGUIState()->m_shown_windows & PARTY)
-	{
-		getGUIState()->m_shown_windows &= ~PARTY;
-	}
-	else
-	{
-		// wenn PartyInfo geoeffnet wird, dann CharInfo schliessen
-		getGUIState()->m_shown_windows &= ~(CHARINFO | QUEST_INFO);
-
-		getGUIState()->m_shown_windows |= PARTY;
-	}
-
-	m_gui_state.m_pressed_key = 0;
-
-	// Geoeffnete Fenster haben sich geaendert
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-void Document::onButtonSkilltreeClicked(bool skill_right, bool use_alternate)
-{
-	if (!checkSubwindowsAllowed())
-		return;
-
-	// Skilltree oeffnen wenn er gerade geschlossen ist und schliessen, wenn er geoeffnet ist
-	if (getGUIState()->m_shown_windows & SKILLTREE)
-	{
-		getGUIState()->m_prefer_right_skill = false;
-		getGUIState()->m_set_right_skill_alternate = false;
-		getGUIState()->m_shown_windows &= ~SKILLTREE;
-	}
-	else
-	{
-		// wenn Skilltree geoeffnet wird, dann Inventar schliessen
-		getGUIState()->m_shown_windows &= ~INVENTORY;
-
-		getGUIState()->m_shown_windows |= SKILLTREE;
-		getGUIState()->m_set_right_skill_alternate = use_alternate;
-		getGUIState()->m_prefer_right_skill =skill_right;
-	}
-
-	m_gui_state.m_pressed_key = 0;
-
-	// Geoeffnete Fenster haben sich geaendert
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-void Document::onButtonOpenChatClicked()
-{
-	// fuer Debugging sehr nuetzlich, das zuzulassen
-	//if (!checkSubwindowsAllowed())
-	//		return;
-
-	// Cchatfenster oeffnen wenn es gerade geschlossen ist und schliessen, wenn es geoeffnet ist
-	if (getGUIState()->m_shown_windows & CHAT)
-	{
-		getGUIState()->m_shown_windows &= ~CHAT;
-	}
-	else
-	{
-		getGUIState()->m_shown_windows |= CHAT;
-	}
-
-	// Geoeffnete Fenster haben sich geaendert
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-void Document::onButtonQuestInfoClicked()
-{
-	if (!checkSubwindowsAllowed())
-		return;
-
-	// Charakterinfo oeffnen wenn es gerade geschlossen ist und schliessen, wenn es geoeffnet ist
-	if (getGUIState()->m_shown_windows & QUEST_INFO)
-	{
-		getGUIState()->m_shown_windows &= ~QUEST_INFO;
-	}
-	else
-	{
-		getGUIState()->m_shown_windows &= ~(PARTY | CHARINFO);
-
-		getGUIState()->m_shown_windows |= QUEST_INFO;
-	}
-
-	// Geoeffnete Fenster haben sich geaendert
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-void Document::onButtonMinimapClicked()
-{
-	if (!checkSubwindowsAllowed())
-		return;
-
-	if (getGUIState()->m_shown_windows & MINIMAP)
-	{
-		getGUIState()->m_shown_windows &= ~MINIMAP;
-	}
-	else
-	{
-		//getGUIState()->m_shown_windows &= ~(PARTY | CHARINFO);
-
-		getGUIState()->m_shown_windows |= MINIMAP;
-	}
-
-	// Geoeffnete Fenster haben sich geaendert
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-
-void Document::onButtonOptionsClicked()
-{
-	if (!checkSubwindowsAllowed() && getGUIState()->m_sheet ==  Document::GAME_SCREEN)
-		return;
-
-	if (getGUIState()->m_shown_windows & OPTIONS)
-	{
-		getGUIState()->m_shown_windows &= ~OPTIONS;
-	}
-	else
-	{
-		getGUIState()->m_shown_windows |= OPTIONS;
-	}
-
-	// Opened windows have changed.
-	m_modified |= WINDOWS_MODIFIED;
-}
-
-
-void Document::onButtonCloseTrade()
-{
-	ClientCommand command;
-	command.m_button = BUTTON_TRADE_END;
-	command.m_id = 0;
-	sendCommand(&command);
-}
-
-void Document::onButtonWorldmap()
-{
-	if (!checkSubwindowsAllowed() && getGUIState()->m_sheet ==  Document::GAME_SCREEN)
-		return;
-
-	if (getGUIState()->m_shown_windows & WORLDMAP)
-	{
-		if (getLocalPlayer()->isUsingWaypoint())
-		{
-			ClientCommand command;
-			command.m_button = BUTTON_WAYPOINT_CHOSE;
-			command.m_id = -1;
-			sendCommand(&command);
-		}
-		else
-		{
-			getGUIState()->m_shown_windows &= ~	WORLDMAP;
-			m_modified |= WINDOWS_MODIFIED;
-		}
-	}
-	else
-	{
-
-		getGUIState()->m_shown_windows |= WORLDMAP;
-		m_modified |= WINDOWS_MODIFIED;
-	}
-
-
-}
-
-void Document::onButtonErrorDialogConfirm()
-{
-	getGUIState()->m_shown_windows &= ~MESSAGE;
-	m_modified |= WINDOWS_MODIFIED;
-    setState(SHUTDOWN_REQUEST);
-}
-
-void Document::onSkipDialogueTextClicked()
-{
-	ClientCommand command;
-	command.m_button = BUTTON_SKIP_DIALOGUE_TEXT;
-	sendCommand(&command);
-}
-
-void Document::onButtonWaypointClicked(int id)
-{
-	if (getLocalPlayer()->isUsingWaypoint())
-	{
-		ClientCommand command;
-		command.m_button = BUTTON_WAYPOINT_CHOSE;
-		command.m_id = id;
-		sendCommand(&command);
-	}
-}
-
-void Document::sendChatMessage(std::string msg)
-{
-
-	if (msg =="")
-	{
-		getGUIState()->m_shown_windows &= ~CHAT;
-		m_modified |= WINDOWS_MODIFIED;
-	}
-	else
-	{
-		World::getWorld()->handleMessage(TranslatableString(msg));
-	}
-}
-
-
-void Document::onSwapEquip()
-{
-	ClientCommand command;
-	command.m_button = BUTTON_SWAP_EQUIP;
-	sendCommand(&command);
-}
-
-
-
-void Document::setLeftAction(Action::ActionType act)
-{
-
-	// wenn kein Spieler gesetzt ist, dann keine Faehigkeit setzen
-	// der lokale Spieler
-	Player* player = static_cast<Player*>(World::getWorld()->getLocalPlayer());
-	if (player==0)
-		return;
-
-
-	Action::ActionInfo* aci = Action::getActionInfo(act);
-
-	// Testen ob die Faehigkeit zur Verfuegung steht
-	if (!player->checkAbility(act))
-	{
-		// Faehigkeit steht nicht zur Verfuegung, abbrechen
-		return;
-	}
-
-	// passive Faehigkeiten koennen nicht auf Maustasten gelegt werden
-	if (aci->m_target_type == Action::PASSIVE)
-		return;
-
-	// Faehigkeiten die nicht auf einfachen Angriffen beruhen koennen nicht auf die linke Maustaste gelegt werden
-	if (aci->m_base_action== "noaction")
-		return;
-
-	DEBUGX("Setting Action %s",act.c_str());
-	m_gui_state.m_left_mouse_pressed = false;
-
-
-	ClientCommand command;
-	command.m_button = BUTTON_SET_LEFT_ACTION;
-	command.m_action = act;
-	sendCommand(&command);
-}
-
-void Document::setRightAction(Action::ActionType act)
-{
-
-	// wenn kein Spieler gesetzt ist, dann keine Faehigkeit setzen
-	// der lokale Spieler
-	Player* player = static_cast<Player*>(World::getWorld()->getLocalPlayer());
-	if (player==0)
-		return;
-
-	Action::ActionInfo* aci = Action::getActionInfo(act);
-
-	// Testen ob die Faehigkeit zur Verfuegung steht
-	if (!player->checkAbility(act))
-	{
-		// Faehigkeit steht nicht zur Verfuegung, abbrechen
-		return;
-	}
-
-	// passive Faehigkeiten koennen nicht auf Maustasten gelegt werden
-	if (aci->m_target_type == Action::PASSIVE)
-		return;
-
-
-	DEBUGX("Setting Action %s",act.c_str());
-	m_gui_state.m_right_mouse_pressed = false;
-
-	ClientCommand command;
-	command.m_button = BUTTON_SET_RIGHT_ACTION;
-	if (getGUIState()->m_set_right_skill_alternate == true)
-	{
-		command.m_button = BUTTON_SET_ALTERNATE_RIGHT_ACTION;
-	}
-	command.m_action = act;
-	sendCommand(&command);
-}
-
-void Document::onSwapRightAction()
-{
-	ClientCommand command;
-	command.m_button = BUTTON_SWAP_RIGHT_ACTION;
-	sendCommand(&command);
-}
-
-std::string Document::getAbilityDescription(Action::ActionType ability)
-{
-	std::ostringstream out_stream;
-	out_stream.str("");
-
-	// der lokale Spieler
-	Player* player = static_cast<Player*>(World::getWorld()->getLocalPlayer());
-
-	if (player !=0 )
-	{
-		// Struktur mit Informationen zur Aktion
-		Action::ActionInfo* aci = Action::getActionInfo(ability);
-		if (aci == 0)
-		{
-			out_stream << "no information on ability "<< ability;
-			return out_stream.str();
-		}
-		// Name der Faehigkeit
-		out_stream << Action::getName(ability);
-
-
-		// Beschreibung
-		out_stream << "\n" << Action::getDescription(ability);
-
-		// Gibt an, ob der Spieler die Faehigkeit besitzt
-		bool avlb = true;
-		if (!player->checkAbility(ability))
-		{
-			// Spieler besitzt Faehigkeit nicht
-			avlb = false;
-
-			PlayerBasicData* pdata = ObjectFactory::getPlayerData(player->getSubtype());
-			if (pdata !=0)
-			{
-				LearnableAbilityMap::iterator it;
-				for (it = pdata->m_learnable_abilities.begin(); it != pdata->m_learnable_abilities.end(); ++it)
-				{
-					if (it->second.m_type == ability)
-					{
-						out_stream <<"\n"<< gettext("Required level")<<": " << it->second.m_req_level;
-					}
-				}
-			}
-
-		}
-
-		// Timerinfo
-		if (aci->m_timer_nr!=0)
-		{
-			out_stream <<"\n"<< gettext("Timer")<<" " << aci->m_timer_nr;
-			out_stream <<"\n"<< gettext("Cast delay")<<": " << (int) aci->m_timer*0.001 << " s";
-		}
-
-		// Schaden
-		// TODO: flexiblere Bedingung
-		if (aci->m_target_type == Action::MELEE || aci->m_target_type == Action::RANGED || aci->m_target_type == Action::CIRCLE)
-		{
-			Damage dmg;
-			player->calcDamage(ability,dmg);
-			std::string dmgstring = dmg.getDamageString(Damage::ABILITY);
-			if (dmgstring !="")
-			{
-				out_stream << "\n" << dmgstring;
-			}
-		}
-
-	}
-
-	return out_stream.str();
-}
-
-bool Document::onKeyPress(KeyCode key)
-{
-
-	// determine action mapped to the key
-	ShortkeyDestination dest;
-	dest = Options::getInstance()->getMappedDestination(key);
-
-	if (m_gui_state.m_shown_windows & SKILLTREE && dest==0)
-	{
-		// Skilltree is displayed
-		// keys are interpreted as attempt to create an ability shortkey
-
-		Action::ActionType act = getGUIState()->m_hover_ability;
-		if (act != "noaction" && getLocalPlayer()->checkAbility(act))
-		{
-			// Action exists and is available
-			Action::ActionInfo* aci = Action::getActionInfo(act);
-
-			// determine if the shortkey should map the ability for left or right mouse button
-			bool left = true;
-			if (getGUIState()->m_prefer_right_skill || aci->m_target_type == Action::PASSIVE || aci->m_base_action== "noaction")
-			{
-				left = false;
-			}
-
-			// determine the internal number of the ability
-			int id =-1;
-			Player* player = getLocalPlayer();
-			std::map<int,LearnableAbility> &ablts = player->getLearnableAbilities();
-			LearnableAbilityMap::iterator it;
-			for (it = ablts.begin(); it != ablts.end(); ++it)
-			{
-				if (it->second.m_type == act)
-				{
-					id = it->first;
-					break;
-				}
-			}
-
-			if (id ==-1)
-				return false;
-
-			// create shortkey
-			if (left)
-			{
-				installShortkey(key,(ShortkeyDestination) (USE_SKILL_LEFT+id));
-				DEBUGX("left short key for action %s %i",act.c_str(), USE_SKILL_LEFT+id);
-			}
-			else
-			{
-				installShortkey(key,(ShortkeyDestination) (USE_SKILL_RIGHT+id));
-				DEBUGX("right short key for action %s %i",act.c_str(),USE_SKILL_RIGHT+id );
-			}
-			return true;
-		}
-
-	}
-
-
-	// if key was not mapped to a shortkey
-	// check ability shortkeys
-	if (dest == 0)
-	{
-		std::map<KeyCode, ShortkeyDestination>::iterator it = m_ability_shortkey_map.find(key);
-		if (it != m_ability_shortkey_map.end())
-			dest = it->second;
-	}
-
-
-	// execute the action, if any mapping was found
-	if (dest != 0)
-	{
-		if (dest == SHOW_INVENTORY)
-		{
-			onButtonInventoryClicked();
-		}
-		else if (dest == SHOW_CHARINFO)
-		{
-			onButtonCharInfoClicked();
-		}
-		else if (dest == SHOW_QUESTINFO)
-		{
-			onButtonQuestInfoClicked();
-		}
-		else if (dest == SHOW_SKILLTREE)
-		{
-			onButtonSkilltreeClicked();
-		}
-		else if (dest == SHOW_MINIMAP)
-		{
-			onButtonMinimapClicked();
-		}
-		else if (dest == SHOW_OPTIONS)
-		{
-			onButtonOptionsClicked();
-		}
-		else if (dest == SWAP_EQUIP)
-		{
-			onSwapEquip();
-		}
-		else if (dest == SWAP_RIGHT_ACTION)
-		{
-			onSwapRightAction();
-		}
-		else if (dest == SHOW_ITEMLABELS)
-		{
-			getGUIState()->m_item_labels = true;
-		}
-		else if (dest >=USE_POTION && dest < USE_POTION+10)
-		{
-			onItemRightClick(Equipement::BELT_ITEMS + (dest-USE_POTION));
-		}
-		else if (dest>=USE_SKILL_LEFT && dest <USE_SKILL_RIGHT)
-		{
-			Player* player = getLocalPlayer();
-			if (player != 0)
-			{
-				std::map<int,LearnableAbility> &ablts = player->getLearnableAbilities();
-
-				if (ablts.count(dest-USE_SKILL_LEFT) >0)
-				{
-					setLeftAction(ablts[dest-USE_SKILL_LEFT].m_type);
-				}
-			}
-		}
-		else if (dest>=USE_SKILL_RIGHT && dest <USE_SKILL_RIGHT+200)
-		{
-			Player* player = getLocalPlayer();
-			if (player != 0)
-			{
-				std::map<int,LearnableAbility> &ablts = player->getLearnableAbilities();
-				if (ablts.count(dest-USE_SKILL_RIGHT) >0)
-				{
-					setRightAction(ablts[dest-USE_SKILL_RIGHT].m_type);
-				}
-			}
-		}
-		else if(dest == SHOW_PARTYMENU)
-		{
-			onButtonPartyInfoClicked();
-		}
-		else if(dest == SHOW_CHATBOX)
-		{
-			onButtonOpenChatClicked();
-
-		}
-		else if (dest == SHOW_MINIMAP)
-		{
-			if (getGUIState()->m_shown_windows & MINIMAP)
-			{
-				getGUIState()->m_shown_windows &= ~MINIMAP;
-			}
-			else
-			{
-				//getGUIState()->m_shown_windows &= ~(PARTY | QUEST_INFO);
-
-				getGUIState()->m_shown_windows |= MINIMAP;
-			}
-			m_modified |= WINDOWS_MODIFIED;
-		}
-		else if(dest == SHOW_CHATBOX_NO_TOGGLE)
-		{
-			// Chatfenster oeffnen wenn es gerade geschlossen ist
-			if (!(getGUIState()->m_shown_windows & CHAT))
-			{
-				getGUIState()->m_shown_windows |= CHAT;
-
-				// Geoeffnete Fenster haben sich geaendert
-				m_modified |= WINDOWS_MODIFIED;
-
-			}
-
-		}
-		else if (dest == CLOSE_ALL)
-		{
-			if (m_gui_state.m_shown_windows == NO_WINDOWS)
-			{
-				onButtonSaveExitClicked();
-			}
-			else if (m_gui_state.m_shown_windows & WORLDMAP)
-			{
-				onButtonWorldmap();
-			}
-			else if (m_gui_state.m_shown_windows & TRADE)
-			{
-				onButtonCloseTrade();
-			}
-			else if (m_gui_state.m_shown_windows & QUESTIONBOX)
-			{
-				// Versuch, aktuelles Gespraech abzubrechen
-				onAnswerClick(-1);
-			}
-			else if (m_gui_state.m_shown_windows & (HOST_GAME | JOIN_GAME | CHAR_CREATE ))
-			{
-				m_gui_state.m_shown_windows = Document::START_MENU;
-				m_modified |= WINDOWS_MODIFIED;
-			}
-			else
-			{
-				m_gui_state.m_shown_windows =  NO_WINDOWS;
-			// Geoeffnete Fenster haben sich geaendert
-				m_modified |= WINDOWS_MODIFIED;
-			}
-		}
-		else if (dest >= CHEAT && dest < CHEAT+10)
-		{
-			emitDebugSignal(dest-CHEAT);
-		}
-		else
-		{
-			return false;
-		}
-
-		return true;
-
-	}
-	return false;
-}
-
-bool  Document::onKeyRelease(KeyCode key)
-{
-	if (m_gui_state.m_pressed_key != 0)
-	{
-		m_gui_state.m_pressed_key = 0;
-	}
-
-	ShortkeyDestination dest = Options::getInstance()->getMappedDestination(key);
-	if (dest != 0)
-	{
-		if (dest == SHOW_ITEMLABELS)
-		{
-			getGUIState()->m_item_labels = false;
-		}
-	}
-	return true;
-}
-
-void Document::update(float time)
-{
-	// Welt eine Zeitscheibe weiter laufen lassen
-	if (World::getWorld() != 0)
-	{
-		// game is paused for single player if save and exit window is shown
-		if (!((getGUIState()->m_shown_windows & SAVE_EXIT) && m_single_player))
-		{
-			World::getWorld()->update(time);
-		}
-
-	}
-
-	if (m_options_timer.getTime() > 60000)
-	{
-		saveSettings();
-		m_options_timer.start();
-	}
-
-	DEBUGX("modified is %i",m_modified);
-	DEBUGX("State is %i",m_state);
-	NetStatus status;
-	switch (m_state)
-	{
-		case INACTIVE:
-			break;
-
-		case START_GAME:
-			startGame(m_server);
-			break;
-
-		case LOAD_SAVEGAME:
-			status = NET_OK;
-			if (!m_server)
-			{
-				status = World::getWorld()->getNetwork()->getSlotStatus();
-			}
-			if (m_server || status == NET_CONNECTED)
-			{
-				loadSavegame();
-			}
-			if (status == NET_REJECTED || status == NET_SLOTS_FULL || status == NET_TIMEOUT)
-			{
-				// Verbindung abgelehnt
-				//m_state = SHUTDOWN;
-                getGUIState()->m_shown_windows = MESSAGE;
-                m_modified |= WINDOWS_MODIFIED;
-			}
-
-
-		case RUNNING:
-			updateContent(time);
-
-			if (m_save_timer.getTime() > 60000)
-			{
-				m_save_timer.start();
-
-				writeSavegame();
-				DEBUGX("saving");
-			}
-
-			if (!m_server)
-			{
-				if (World::getWorld()->getNetwork()->getSlotStatus() == NET_TIMEOUT)
-				{
-					setState(INACTIVE);
-                    getGUIState()->m_shown_windows = MESSAGE;
-                    m_modified |= WINDOWS_MODIFIED;
-				}
-			}
-
-			break;
-
-		case SHUTDOWN_REQUEST:
-			updateContent(time);
-			m_shutdown_timer += time;
-
-			setState(SHUTDOWN_WRITE_SAVEGAME);
-
-			if (m_shutdown_timer>400)
-			{
-				setState(SHUTDOWN);
-			}
-			break;
-
-		case SHUTDOWN_WRITE_SAVEGAME:
-			// Savegame schreiben
-			writeSavegame();
-
-			m_state = SHUTDOWN;
-			break;
-
-		case SHUTDOWN:
-			// Spielwelt abschalten
-
-			World::deleteWorld();
-
-			getGUIState()->m_sheet= MAIN_MENU;
-			getGUIState()->m_shown_windows = NO_WINDOWS;
-
-			m_state = INACTIVE;
-
-			m_modified =GUISHEET_MODIFIED | WINDOWS_MODIFIED;
-
-			saveSettings();
-			break;
-
-		default:
-			break;
-	}
-	DEBUGX("done");
-}
-
-void Document::updateContent(float time)
-{
-	DEBUGX("update content");
-
-	Player* player = static_cast<Player*>(World::getWorld()->getLocalPlayer());
-	if (player==0)
-	{
-		DEBUGX("no local player");
-		return;
-	}
-
-	// Fenster einstellen, die automatisch geoeffnet werden
-	int wmask = getGUIState()->m_shown_windows;
-	if (player->getTradeInfo().m_trade_partner != 0 && getGUIState()->m_shown_windows != SAVE_EXIT)
-	{
-		if (getGUIState()->m_shown_windows != (TRADE | INVENTORY))
-		{
-			getGUIState()->m_shown_windows = TRADE | INVENTORY;
-			m_modified |= WINDOWS_MODIFIED;
-		}
-	}
-	else if (player->getDialogueId() != 0
-				|| (player->getRegion() !=0 && player->getRegion()->getCutsceneMode () == true))
-	{
-		// Chat ist fuer Debugging zugeschaltet
-		if ((getGUIState()->m_shown_windows & (~(QUESTIONBOX | SAVE_EXIT | CHAT))) != 0)
-		{
-			getGUIState()->m_shown_windows &= (QUESTIONBOX  | SAVE_EXIT | CHAT);
-			m_modified |= WINDOWS_MODIFIED;
-		}
-	}
-
-	if (player->getTradeInfo().m_trade_partner == 0 && (wmask & TRADE))
-	{
-		getGUIState()->m_shown_windows &= ~(TRADE | INVENTORY);
-		m_modified |= WINDOWS_MODIFIED;
-	}
-
-	if (player->isUsingWaypoint() && getGUIState()->m_shown_windows !=	WORLDMAP)
-	{
-		getGUIState()->m_shown_windows = WORLDMAP;
-		m_modified |= WINDOWS_MODIFIED;
-	}
-
-	if (!player->isUsingWaypoint() && (wmask & WORLDMAP))
-	{
-		getGUIState()->m_shown_windows &= ~WORLDMAP;
-		m_modified |= WINDOWS_MODIFIED;
-	}
-
-	/*
-	if (player->getRegion() !=0 && player->getRegion()->getCutsceneMode())
-	{
-		if ((getGUIState()->m_shown_windows & ~SAVE_EXIT) != 0)
-		{
-			getGUIState()->m_shown_windows &= SAVE_EXIT;
-			m_modified |= WINDOWS_MODIFIED;
-		}
-	}
-*/
-	if (m_gui_state.m_left_mouse_pressed)
-	{
-		m_gui_state.m_left_mouse_pressed_time += time;
-		if (m_gui_state.m_left_mouse_pressed_time >= 200 ||
-				  (m_gui_state.m_left_mouse_pressed_time >=40 && player->getAction()->m_type == "noaction") )
-		{
-			ClientCommand command;
-
-			command.m_button=LEFT_MOUSE_BUTTON;
-			if (m_gui_state.m_shift_hold)
-			{
-				command.m_button=LEFT_SHIFT_MOUSE_BUTTON;
-			}
-			updateClickedObjectId();
-
-			command.m_goal = m_gui_state.m_clicked;
-			command.m_id = m_gui_state.m_clicked_object_id;
-			command.m_action = player->getLeftAction();
-			command.m_number=0;
-
-			m_gui_state.m_left_mouse_pressed_time=0;
-			sendCommand(&command);
-
-		}
-	}
-
-	if (m_gui_state.m_right_mouse_pressed)
-	{
-		DEBUGX("rechte Maustaste festgehalten");
-		m_gui_state.m_right_mouse_pressed_time += time;
-
-		if (m_gui_state.m_right_mouse_pressed_time>= 200 ||
-				  (m_gui_state.m_left_mouse_pressed_time >=40 && player->getAction()->m_type == "noaction"))
-		{
-			ClientCommand command;
-			updateClickedObjectId();
-
-			command.m_button=RIGHT_MOUSE_BUTTON;
-			command.m_goal = m_gui_state.m_clicked;
-			command.m_id = m_gui_state.m_clicked_object_id;
-			command.m_action = player->getRightAction();
-			command.m_number=0;
-
-			m_gui_state.m_right_mouse_pressed_time=0;
-			sendCommand(&command);
-
-		}
-
-	}
-
-
-
-
-}
-
-void Document::updateClickedObjectId()
-{
-	Player* player = static_cast<Player*>(World::getWorld()->getLocalPlayer());
-	Region* reg = player->getRegion();
-	if (reg == 0)
-		return;
-
-	// select new target if the old one is gone or inactive
-	if (m_gui_state.m_clicked_object_id != 0 && m_gui_state.m_cursor_object_id != 0)
-	{
-		GameObject* go = reg->getObject(m_gui_state.m_clicked_object_id);
-		if (go == 0 || go->getState() != WorldObject::STATE_ACTIVE)
-		{
-			// TODO: better check if the target is appropriate for the action
-			go = reg->getObject(m_gui_state.m_cursor_object_id);
-			Creature* cr = dynamic_cast<Creature*>(go);
-			if ( cr != 0 && World::getWorld()->getRelation(player->getFraction(),cr) == Fraction::HOSTILE)
-			{
-				m_gui_state.m_clicked_object_id = m_gui_state.m_cursor_object_id;
-				DEBUGX("new target %i %i",m_gui_state.m_clicked_object_id, player->getId());
-			}
-		}
-	}
-}
-
-void Document::writeSavegame(bool writeShortkeys)
-{
-	if (getLocalPlayer()==0)
-		return;
-
-	CharConv* save;
-
-
-
-	std::stringstream* pstr = new std::stringstream;
-	save = new StdStreamConv(pstr);
-
-	getLocalPlayer()->toSavegame(save);
-
-	// Shortkeys hinzufuegen
-	if (writeShortkeys)
-	{
-		
-		ShortkeyMap::iterator it;
-		int nr =0;
-		for (it = m_ability_shortkey_map.begin(); it != m_ability_shortkey_map.end(); ++it)
-		{
-			if (it->second >= USE_SKILL_LEFT && it->second < USE_SKILL_RIGHT + 200)
-				nr ++;
-		}
-		save->printNewline();
-		save->toBuffer(nr);
-		save->printNewline();
-		for (it = m_ability_shortkey_map.begin(); it != m_ability_shortkey_map.end(); ++it)
-		{
-			if (it->second >= USE_SKILL_LEFT && it->second < USE_SKILL_RIGHT + 200)
-			{
-				save->toBuffer(static_cast<short>(it->first));
-				save->toBuffer(static_cast<short>(it->second));
-				save->printNewline();
-			}
-		}
-	}
-	else
-	{
-		save->printNewline();
-		save->toBuffer(0);
-	}
-
-	// Savegame schreiben (ansynchron)
-	std::pair<Document*, CharConv*>* param = new std::pair<Document*, CharConv*>(this,save);
-	
-	// Savegame schreiben
-	std::stringstream* stream = dynamic_cast<std::stringstream*> (static_cast<StdStreamConv*>(save)->getStream());
-	char* bp=0;
-	int len=0;
-	char bin ='0';
-	
-	// binary savegames are not used anymore
-	
-	
-	// Daten byteweise in Datei schreiben
-	std::ofstream file;
-	if (bin =='1')
-	{
-		file.open(m_save_file.c_str(),std::ios::out | std::ios::binary);
-	}
-	else
-	{
-		file.open(m_save_file.c_str());
-	}
-	if ( file.is_open() )
-	{
-		file << bin;
-		if (bin =='1')
-		{
-			file.write((char*) (&len),4);
-			file.write(bp,len);
-		}
-		else
-		{
-			file << stream->str();
-			DEBUGX("save: \n %s",stream->str().c_str());
-		}
-		
-		file.close();
-	}
-	else
-	{
-		ERRORMSG("cannot open save file: %s",m_save_file.c_str());
-	}
-	if (stream != 0)
-	{
-		delete stream;
-	}
-	
-
-}
-
-
-void Document::saveSettings()
-{
-    Options::getInstance()->writeToFile(SumwarsHelper::userPath() + "/options.xml");
-}
-
-void Document::loadSettings()
-{
-    Options::getInstance()->readFromFile(SumwarsHelper::userPath() + "/options.xml");
-}
-
-Player*  Document::getLocalPlayer()
-{
-	if (World::getWorld() ==0)
-		return m_temp_player;
-
-	return static_cast<Player*>(World::getWorld()->getLocalPlayer());
-}
+	return ok;
+}
+
+
+
+void Document::onButtonStartSinglePlayer ()
+{
+	// The player is a host himself (or herself)
+	setServer (true);
+	m_single_player = true;
+
+	// Set the state and allow the connection to be established.
+	setState (Document::START_GAME);
+}
+
+
+
+void Document::onButtonHostGame()
+{
+	DEBUG("Host Game");
+	if (m_save_file == "")
+	{
+		// Show a notification.
+		CEGUI::WindowManager& win_mgr = CEGUI::WindowManager::getSingleton();
+		CEGUI::FrameWindow* message = (CEGUI::FrameWindow*) win_mgr.getWindow("WarningDialogWindow");
+		message->setInheritsAlpha(false);
+		message->setVisible(true);
+		message->setModalState(true);
+		win_mgr.getWindow( "WarningDialogLabel")->setText((CEGUI::utf8*) gettext("Please select a character first!"));
+
+		DEBUG ("Warning: Tried to host a game without a selected char!");
+		return;
+	}
+	getGUIState()->m_shown_windows |= HOST_GAME;
+	getGUIState()->m_shown_windows &= ~START_MENU;
+
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+void Document::onButtonJoinGame()
+{
+	if (m_save_file == "")
+	{
+		// Show a notification.
+		CEGUI::WindowManager& win_mgr = CEGUI::WindowManager::getSingleton();
+		CEGUI::FrameWindow* message = (CEGUI::FrameWindow*) win_mgr.getWindow("WarningDialogWindow");
+		message->setInheritsAlpha(false);
+		message->setVisible(true);
+		message->setModalState(true);
+		win_mgr.getWindow( "WarningDialogLabel")->setText((CEGUI::utf8*) gettext("Please select a character first!"));
+
+		DEBUG ("Warning: Tried to join a game without a selected char!");
+		return;
+	}
+	getGUIState()->m_shown_windows |= JOIN_GAME;
+	getGUIState()->m_shown_windows &= ~START_MENU;
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+void Document::onButtonStartHostGame()
+{
+	DEBUG("start multiplayer game");
+	// Spieler ist selbst der Host
+	setServer(true);
+	m_single_player = false;
+
+	// Verbindung aufbauen
+	setState(Document::START_GAME);
+}
+
+
+
+void Document::onButtonStartJoinGame()
+{
+	setServer(false);
+	m_single_player = false;
+	
+	// starten
+	setState(Document::START_GAME);
+}
+
+void Document::onButtonInventoryClicked()
+{
+	if (!checkSubwindowsAllowed())
+		return;
+
+	// Inventar oeffnen wenn es gerade geschlossen ist und schliessen, wenn es geoeffnet ist
+	if (getGUIState()->m_shown_windows & INVENTORY)
+	{
+
+		getGUIState()->m_shown_windows &= ~INVENTORY;
+
+		// der lokale Spieler
+		Player* pl = static_cast<Player*>( World::getWorld()->getLocalPlayer());
+		if (pl==0)
+			return;
+
+		// Item das aktuell in der Hand ist fallen lassen
+		if (pl->getEquipement()->getItem(Equipement::CURSOR_ITEM)!=0)
+		{
+			dropCursorItem();
+		}
+	}
+	else
+	{
+		// wenn Inventar geoeffnet wird, dann Skilltree schliessen
+		getGUIState()->m_shown_windows &= ~SKILLTREE;
+		m_gui_state.m_pressed_key = 0;
+
+		getGUIState()->m_shown_windows |= INVENTORY;
+
+
+
+	}
+
+	// Geoeffnete Fenster haben sich geaendert
+	m_modified |= WINDOWS_MODIFIED;
+
+}
+
+void Document::onButtonCharInfoClicked()
+{
+	if (!checkSubwindowsAllowed())
+		return;
+
+	// Charakterinfo oeffnen wenn es gerade geschlossen ist und schliessen, wenn es geoeffnet ist
+	if (getGUIState()->m_shown_windows & CHARINFO)
+	{
+		getGUIState()->m_shown_windows &= ~CHARINFO;
+	}
+	else
+	{
+		getGUIState()->m_shown_windows &= ~(PARTY | QUEST_INFO);
+
+		getGUIState()->m_shown_windows |= CHARINFO;
+	}
+
+	// Geoeffnete Fenster haben sich geaendert
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+void Document::onButtonPartyInfoClicked()
+{
+	if (!checkSubwindowsAllowed())
+		return;
+
+	// PartyInfo oeffnen wenn es gerade geschlossen ist und schliessen, wenn er geoeffnet ist
+	if (getGUIState()->m_shown_windows & PARTY)
+	{
+		getGUIState()->m_shown_windows &= ~PARTY;
+	}
+	else
+	{
+		// wenn PartyInfo geoeffnet wird, dann CharInfo schliessen
+		getGUIState()->m_shown_windows &= ~(CHARINFO | QUEST_INFO);
+
+		getGUIState()->m_shown_windows |= PARTY;
+	}
+
+	m_gui_state.m_pressed_key = 0;
+
+	// Geoeffnete Fenster haben sich geaendert
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+void Document::onButtonSkilltreeClicked(bool skill_right, bool use_alternate)
+{
+	if (!checkSubwindowsAllowed())
+		return;
+
+	// Skilltree oeffnen wenn er gerade geschlossen ist und schliessen, wenn er geoeffnet ist
+	if (getGUIState()->m_shown_windows & SKILLTREE)
+	{
+		getGUIState()->m_prefer_right_skill = false;
+		getGUIState()->m_set_right_skill_alternate = false;
+		getGUIState()->m_shown_windows &= ~SKILLTREE;
+	}
+	else
+	{
+		// wenn Skilltree geoeffnet wird, dann Inventar schliessen
+		getGUIState()->m_shown_windows &= ~INVENTORY;
+
+		getGUIState()->m_shown_windows |= SKILLTREE;
+		getGUIState()->m_set_right_skill_alternate = use_alternate;
+		getGUIState()->m_prefer_right_skill =skill_right;
+	}
+
+	m_gui_state.m_pressed_key = 0;
+
+	// Geoeffnete Fenster haben sich geaendert
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+void Document::onButtonOpenChatClicked()
+{
+	// fuer Debugging sehr nuetzlich, das zuzulassen
+	//if (!checkSubwindowsAllowed())
+	//		return;
+
+	// Cchatfenster oeffnen wenn es gerade geschlossen ist und schliessen, wenn es geoeffnet ist
+	if (getGUIState()->m_shown_windows & CHAT)
+	{
+		getGUIState()->m_shown_windows &= ~CHAT;
+	}
+	else
+	{
+		getGUIState()->m_shown_windows |= CHAT;
+	}
+
+	// Geoeffnete Fenster haben sich geaendert
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+void Document::onButtonQuestInfoClicked()
+{
+	if (!checkSubwindowsAllowed())
+		return;
+
+	// Charakterinfo oeffnen wenn es gerade geschlossen ist und schliessen, wenn es geoeffnet ist
+	if (getGUIState()->m_shown_windows & QUEST_INFO)
+	{
+		getGUIState()->m_shown_windows &= ~QUEST_INFO;
+	}
+	else
+	{
+		getGUIState()->m_shown_windows &= ~(PARTY | CHARINFO);
+
+		getGUIState()->m_shown_windows |= QUEST_INFO;
+	}
+
+	// Geoeffnete Fenster haben sich geaendert
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+void Document::onButtonMinimapClicked()
+{
+	if (!checkSubwindowsAllowed())
+		return;
+
+	if (getGUIState()->m_shown_windows & MINIMAP)
+	{
+		getGUIState()->m_shown_windows &= ~MINIMAP;
+	}
+	else
+	{
+		//getGUIState()->m_shown_windows &= ~(PARTY | CHARINFO);
+
+		getGUIState()->m_shown_windows |= MINIMAP;
+	}
+
+	// Geoeffnete Fenster haben sich geaendert
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+
+void Document::onButtonOptionsClicked()
+{
+	if (!checkSubwindowsAllowed() && getGUIState()->m_sheet ==  Document::GAME_SCREEN)
+		return;
+
+	if (getGUIState()->m_shown_windows & OPTIONS)
+	{
+		getGUIState()->m_shown_windows &= ~OPTIONS;
+	}
+	else
+	{
+		getGUIState()->m_shown_windows |= OPTIONS;
+	}
+
+	// Opened windows have changed.
+	m_modified |= WINDOWS_MODIFIED;
+}
+
+
+void Document::onButtonCloseTrade()
+{
+	ClientCommand command;
+	command.m_button = BUTTON_TRADE_END;
+	command.m_id = 0;
+	sendCommand(&command);
+}
+
+void Document::onButtonWorldmap()
+{
+	if (!checkSubwindowsAllowed() && getGUIState()->m_sheet ==  Document::GAME_SCREEN)
+		return;
+
+	if (getGUIState()->m_shown_windows & WORLDMAP)
+	{
+		if (getLocalPlayer()->isUsingWaypoint())
+		{
+			ClientCommand command;
+			command.m_button = BUTTON_WAYPOINT_CHOSE;
+			command.m_id = -1;
+			sendCommand(&command);
+		}
+		else
+		{
+			getGUIState()->m_shown_windows &= ~	WORLDMAP;
+			m_modified |= WINDOWS_MODIFIED;
+		}
+	}
+	else
+	{
+
+		getGUIState()->m_shown_windows |= WORLDMAP;
+		m_modified |= WINDOWS_MODIFIED;
+	}
+
+
+}
+
+void Document::onButtonErrorDialogConfirm()
+{
+	getGUIState()->m_shown_windows &= ~MESSAGE;
+	m_modified |= WINDOWS_MODIFIED;
+    setState(SHUTDOWN_REQUEST);
+}
+
+void Document::onSkipDialogueTextClicked()
+{
+	ClientCommand command;
+	command.m_button = BUTTON_SKIP_DIALOGUE_TEXT;
+	sendCommand(&command);
+}
+
+void Document::onButtonWaypointClicked(int id)
+{
+	if (getLocalPlayer()->isUsingWaypoint())
+	{
+		ClientCommand command;
+		command.m_button = BUTTON_WAYPOINT_CHOSE;
+		command.m_id = id;
+		sendCommand(&command);
+	}
+}
+
+void Document::sendChatMessage(std::string msg)
+{
+
+	if (msg =="")
+	{
+		getGUIState()->m_shown_windows &= ~CHAT;
+		m_modified |= WINDOWS_MODIFIED;
+	}
+	else
+	{
+		World::getWorld()->handleMessage(TranslatableString(msg));
+	}
+}
+
+
+void Document::onSwapEquip()
+{
+	ClientCommand command;
+	command.m_button = BUTTON_SWAP_EQUIP;
+	sendCommand(&command);
+}
+
+
+
+void Document::setLeftAction(Action::ActionType act)
+{
+
+	// wenn kein Spieler gesetzt ist, dann keine Faehigkeit setzen
+	// der lokale Spieler
+	Player* player = static_cast<Player*>(World::getWorld()->getLocalPlayer());
+	if (player==0)
+		return;
+
+
+	Action::ActionInfo* aci = Action::getActionInfo(act);
+
+	// Testen ob die Faehigkeit zur Verfuegung steht
+	if (!player->checkAbility(act))
+	{
+		// Faehigkeit steht nicht zur Verfuegung, abbrechen
+		return;
+	}
+
+	// passive Faehigkeiten koennen nicht auf Maustasten gelegt werden
+	if (aci->m_target_type == Action::PASSIVE)
+		return;
+
+	// Faehigkeiten die nicht auf einfachen Angriffen beruhen koennen nicht auf die linke Maustaste gelegt werden
+	if (aci->m_base_action== "noaction")
+		return;
+
+	DEBUGX("Setting Action %s",act.c_str());
+	m_gui_state.m_left_mouse_pressed = false;
+
+
+	ClientCommand command;
+	command.m_button = BUTTON_SET_LEFT_ACTION;
+	command.m_action = act;
+	sendCommand(&command);
+}
+
+void Document::setRightAction(Action::ActionType act)
+{
+
+	// wenn kein Spieler gesetzt ist, dann keine Faehigkeit setzen
+	// der lokale Spieler
+	Player* player = static_cast<Player*>(World::getWorld()->getLocalPlayer());
+	if (player==0)
+		return;
+
+	Action::ActionInfo* aci = Action::getActionInfo(act);
+
+	// Testen ob die Faehigkeit zur Verfuegung steht
+	if (!player->checkAbility(act))
+	{
+		// Faehigkeit steht nicht zur Verfuegung, abbrechen
+		return;
+	}
+
+	// passive Faehigkeiten koennen nicht auf Maustasten gelegt werden
+	if (aci->m_target_type == Action::PASSIVE)
+		return;
+
+
+	DEBUGX("Setting Action %s",act.c_str());
+	m_gui_state.m_right_mouse_pressed = false;
+
+	ClientCommand command;
+	command.m_button = BUTTON_SET_RIGHT_ACTION;
+	if (getGUIState()->m_set_right_skill_alternate == true)
+	{
+		command.m_button = BUTTON_SET_ALTERNATE_RIGHT_ACTION;
+	}
+	command.m_action = act;
+	sendCommand(&command);
+}
+
+void Document::onSwapRightAction()
+{
+	ClientCommand command;
+	command.m_button = BUTTON_SWAP_RIGHT_ACTION;
+	sendCommand(&command);
+}
+
+std::string Document::getAbilityDescription(Action::ActionType ability)
+{
+	std::ostringstream out_stream;
+	out_stream.str("");
+
+	// der lokale Spieler
+	Player* player = static_cast<Player*>(World::getWorld()->getLocalPlayer());
+
+	if (player !=0 )
+	{
+		// Struktur mit Informationen zur Aktion
+		Action::ActionInfo* aci = Action::getActionInfo(ability);
+		if (aci == 0)
+		{
+			out_stream << "no information on ability "<< ability;
+			return out_stream.str();
+		}
+		// Name der Faehigkeit
+		out_stream << Action::getName(ability);
+
+
+		// Beschreibung
+		out_stream << "\n" << Action::getDescription(ability);
+
+		// Gibt an, ob der Spieler die Faehigkeit besitzt
+		bool avlb = true;
+		if (!player->checkAbility(ability))
+		{
+			// Spieler besitzt Faehigkeit nicht
+			avlb = false;
+
+			PlayerBasicData* pdata = ObjectFactory::getPlayerData(player->getSubtype());
+			if (pdata !=0)
+			{
+				LearnableAbilityMap::iterator it;
+				for (it = pdata->m_learnable_abilities.begin(); it != pdata->m_learnable_abilities.end(); ++it)
+				{
+					if (it->second.m_type == ability)
+					{
+						out_stream <<"\n"<< gettext("Required level")<<": " << it->second.m_req_level;
+					}
+				}
+			}
+
+		}
+
+		// Timerinfo
+		if (aci->m_timer_nr!=0)
+		{
+			out_stream <<"\n"<< gettext("Timer")<<" " << aci->m_timer_nr;
+			out_stream <<"\n"<< gettext("Cast delay")<<": " << (int) aci->m_timer*0.001 << " s";
+		}
+
+		// Schaden
+		// TODO: flexiblere Bedingung
+		if (aci->m_target_type == Action::MELEE || aci->m_target_type == Action::RANGED || aci->m_target_type == Action::CIRCLE)
+		{
+			Damage dmg;
+			player->calcDamage(ability,dmg);
+			std::string dmgstring = dmg.getDamageString(Damage::ABILITY);
+			if (dmgstring !="")
+			{
+				out_stream << "\n" << dmgstring;
+			}
+		}
+
+	}
+
+	return out_stream.str();
+}
+
+bool Document::onKeyPress(KeyCode key)
+{
+
+	// determine action mapped to the key
+	ShortkeyDestination dest;
+	dest = Options::getInstance()->getMappedDestination(key);
+
+	if (m_gui_state.m_shown_windows & SKILLTREE && dest==0)
+	{
+		// Skilltree is displayed
+		// keys are interpreted as attempt to create an ability shortkey
+
+		Action::ActionType act = getGUIState()->m_hover_ability;
+		if (act != "noaction" && getLocalPlayer()->checkAbility(act))
+		{
+			// Action exists and is available
+			Action::ActionInfo* aci = Action::getActionInfo(act);
+
+			// determine if the shortkey should map the ability for left or right mouse button
+			bool left = true;
+			if (getGUIState()->m_prefer_right_skill || aci->m_target_type == Action::PASSIVE || aci->m_base_action== "noaction")
+			{
+				left = false;
+			}
+
+			// determine the internal number of the ability
+			int id =-1;
+			Player* player = getLocalPlayer();
+			std::map<int,LearnableAbility> &ablts = player->getLearnableAbilities();
+			LearnableAbilityMap::iterator it;
+			for (it = ablts.begin(); it != ablts.end(); ++it)
+			{
+				if (it->second.m_type == act)
+				{
+					id = it->first;
+					break;
+				}
+			}
+
+			if (id ==-1)
+				return false;
+
+			// create shortkey
+			if (left)
+			{
+				installShortkey(key,(ShortkeyDestination) (USE_SKILL_LEFT+id));
+				DEBUGX("left short key for action %s %i",act.c_str(), USE_SKILL_LEFT+id);
+			}
+			else
+			{
+				installShortkey(key,(ShortkeyDestination) (USE_SKILL_RIGHT+id));
+				DEBUGX("right short key for action %s %i",act.c_str(),USE_SKILL_RIGHT+id );
+			}
+			return true;
+		}
+
+	}
+
+
+	// if key was not mapped to a shortkey
+	// check ability shortkeys
+	if (dest == 0)
+	{
+		std::map<KeyCode, ShortkeyDestination>::iterator it = m_ability_shortkey_map.find(key);
+		if (it != m_ability_shortkey_map.end())
+			dest = it->second;
+	}
+
+
+	// execute the action, if any mapping was found
+	if (dest != 0)
+	{
+		if (dest == SHOW_INVENTORY)
+		{
+			onButtonInventoryClicked();
+		}
+		else if (dest == SHOW_CHARINFO)
+		{
+			onButtonCharInfoClicked();
+		}
+		else if (dest == SHOW_QUESTINFO)
+		{
+			onButtonQuestInfoClicked();
+		}
+		else if (dest == SHOW_SKILLTREE)
+		{
+			onButtonSkilltreeClicked();
+		}
+		else if (dest == SHOW_MINIMAP)
+		{
+			onButtonMinimapClicked();
+		}
+		else if (dest == SHOW_OPTIONS)
+		{
+			onButtonOptionsClicked();
+		}
+		else if (dest == SWAP_EQUIP)
+		{
+			onSwapEquip();
+		}
+		else if (dest == SWAP_RIGHT_ACTION)
+		{
+			onSwapRightAction();
+		}
+		else if (dest == SHOW_ITEMLABELS)
+		{
+			getGUIState()->m_item_labels = true;
+		}
+		else if (dest >=USE_POTION && dest < USE_POTION+10)
+		{
+			onItemRightClick(Equipement::BELT_ITEMS + (dest-USE_POTION));
+		}
+		else if (dest>=USE_SKILL_LEFT && dest <USE_SKILL_RIGHT)
+		{
+			Player* player = getLocalPlayer();
+			if (player != 0)
+			{
+				std::map<int,LearnableAbility> &ablts = player->getLearnableAbilities();
+
+				if (ablts.count(dest-USE_SKILL_LEFT) >0)
+				{
+					setLeftAction(ablts[dest-USE_SKILL_LEFT].m_type);
+				}
+			}
+		}
+		else if (dest>=USE_SKILL_RIGHT && dest <USE_SKILL_RIGHT+200)
+		{
+			Player* player = getLocalPlayer();
+			if (player != 0)
+			{
+				std::map<int,LearnableAbility> &ablts = player->getLearnableAbilities();
+				if (ablts.count(dest-USE_SKILL_RIGHT) >0)
+				{
+					setRightAction(ablts[dest-USE_SKILL_RIGHT].m_type);
+				}
+			}
+		}
+		else if(dest == SHOW_PARTYMENU)
+		{
+			onButtonPartyInfoClicked();
+		}
+		else if(dest == SHOW_CHATBOX)
+		{
+			onButtonOpenChatClicked();
+
+		}
+		else if (dest == SHOW_MINIMAP)
+		{
+			if (getGUIState()->m_shown_windows & MINIMAP)
+			{
+				getGUIState()->m_shown_windows &= ~MINIMAP;
+			}
+			else
+			{
+				//getGUIState()->m_shown_windows &= ~(PARTY | QUEST_INFO);
+
+				getGUIState()->m_shown_windows |= MINIMAP;
+			}
+			m_modified |= WINDOWS_MODIFIED;
+		}
+		else if(dest == SHOW_CHATBOX_NO_TOGGLE)
+		{
+			// Chatfenster oeffnen wenn es gerade geschlossen ist
+			if (!(getGUIState()->m_shown_windows & CHAT))
+			{
+				getGUIState()->m_shown_windows |= CHAT;
+
+				// Geoeffnete Fenster haben sich geaendert
+				m_modified |= WINDOWS_MODIFIED;
+
+			}
+
+		}
+		else if (dest == CLOSE_ALL)
+		{
+			if (m_gui_state.m_shown_windows == NO_WINDOWS)
+			{
+				onButtonSaveExitClicked();
+			}
+			else if (m_gui_state.m_shown_windows & WORLDMAP)
+			{
+				onButtonWorldmap();
+			}
+			else if (m_gui_state.m_shown_windows & TRADE)
+			{
+				onButtonCloseTrade();
+			}
+			else if (m_gui_state.m_shown_windows & QUESTIONBOX)
+			{
+				// Versuch, aktuelles Gespraech abzubrechen
+				onAnswerClick(-1);
+			}
+			else if (m_gui_state.m_shown_windows & (HOST_GAME | JOIN_GAME | CHAR_CREATE ))
+			{
+				m_gui_state.m_shown_windows = Document::START_MENU;
+				m_modified |= WINDOWS_MODIFIED;
+			}
+			else
+			{
+				m_gui_state.m_shown_windows =  NO_WINDOWS;
+			// Geoeffnete Fenster haben sich geaendert
+				m_modified |= WINDOWS_MODIFIED;
+			}
+		}
+		else if (dest >= CHEAT && dest < CHEAT+10)
+		{
+			emitDebugSignal(dest-CHEAT);
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+
+	}
+	return false;
+}
+
+bool  Document::onKeyRelease(KeyCode key)
+{
+	if (m_gui_state.m_pressed_key != 0)
+	{
+		m_gui_state.m_pressed_key = 0;
+	}
+
+	ShortkeyDestination dest = Options::getInstance()->getMappedDestination(key);
+	if (dest != 0)
+	{
+		if (dest == SHOW_ITEMLABELS)
+		{
+			getGUIState()->m_item_labels = false;
+		}
+	}
+	return true;
+}
+
+void Document::update(float time)
+{
+	// Welt eine Zeitscheibe weiter laufen lassen
+	if (World::getWorld() != 0)
+	{
+		// game is paused for single player if save and exit window is shown
+		if (!((getGUIState()->m_shown_windows & SAVE_EXIT) && m_single_player))
+		{
+			World::getWorld()->update(time);
+		}
+
+	}
+
+	if (m_options_timer.getTime() > 60000)
+	{
+		saveSettings();
+		m_options_timer.start();
+	}
+
+	DEBUGX("modified is %i",m_modified);
+	DEBUGX("State is %i",m_state);
+	NetStatus status;
+	switch (m_state)
+	{
+		case INACTIVE:
+			break;
+
+		case START_GAME:
+			startGame(m_server);
+			break;
+
+		case LOAD_SAVEGAME:
+			status = NET_OK;
+			if (!m_server)
+			{
+				status = World::getWorld()->getNetwork()->getSlotStatus();
+			}
+			if (m_server || status == NET_CONNECTED)
+			{
+				loadSavegame();
+			}
+			if (status == NET_REJECTED || status == NET_SLOTS_FULL || status == NET_TIMEOUT)
+			{
+				// Verbindung abgelehnt
+				//m_state = SHUTDOWN;
+                getGUIState()->m_shown_windows = MESSAGE;
+                m_modified |= WINDOWS_MODIFIED;
+			}
+
+
+		case RUNNING:
+			updateContent(time);
+
+			if (m_save_timer.getTime() > 60000)
+			{
+				m_save_timer.start();
+
+				writeSavegame();
+				DEBUGX("saving");
+			}
+
+			if (!m_server)
+			{
+				if (World::getWorld()->getNetwork()->getSlotStatus() == NET_TIMEOUT)
+				{
+					setState(INACTIVE);
+                    getGUIState()->m_shown_windows = MESSAGE;
+                    m_modified |= WINDOWS_MODIFIED;
+				}
+			}
+
+			break;
+
+		case SHUTDOWN_REQUEST:
+			updateContent(time);
+			m_shutdown_timer += time;
+
+			setState(SHUTDOWN_WRITE_SAVEGAME);
+
+			if (m_shutdown_timer>400)
+			{
+				setState(SHUTDOWN);
+			}
+			break;
+
+		case SHUTDOWN_WRITE_SAVEGAME:
+			// Savegame schreiben
+			writeSavegame();
+
+			m_state = SHUTDOWN;
+			break;
+
+		case SHUTDOWN:
+			// Spielwelt abschalten
+
+			World::deleteWorld();
+
+			getGUIState()->m_sheet= MAIN_MENU;
+			getGUIState()->m_shown_windows = START_MENU;
+			m_modified =WINDOWS_MODIFIED;
+
+			m_state = INACTIVE;
+
+			m_modified =GUISHEET_MODIFIED | WINDOWS_MODIFIED;
+
+			saveSettings();
+			break;
+
+		default:
+			break;
+	}
+	DEBUGX("done");
+}
+
+void Document::updateContent(float time)
+{
+	DEBUGX("update content");
+
+	Player* player = static_cast<Player*>(World::getWorld()->getLocalPlayer());
+	if (player==0)
+	{
+		DEBUGX("no local player");
+		return;
+	}
+
+	// Fenster einstellen, die automatisch geoeffnet werden
+	int wmask = getGUIState()->m_shown_windows;
+	if (player->getTradeInfo().m_trade_partner != 0 && getGUIState()->m_shown_windows != SAVE_EXIT)
+	{
+		if (getGUIState()->m_shown_windows != (TRADE | INVENTORY))
+		{
+			getGUIState()->m_shown_windows = TRADE | INVENTORY;
+			m_modified |= WINDOWS_MODIFIED;
+		}
+	}
+	else if (player->getDialogueId() != 0
+				|| (player->getRegion() !=0 && player->getRegion()->getCutsceneMode () == true))
+	{
+		// Chat ist fuer Debugging zugeschaltet
+		if ((getGUIState()->m_shown_windows & (~(QUESTIONBOX | SAVE_EXIT | CHAT))) != 0)
+		{
+			getGUIState()->m_shown_windows &= (QUESTIONBOX  | SAVE_EXIT | CHAT);
+			m_modified |= WINDOWS_MODIFIED;
+		}
+	}
+
+	if (player->getTradeInfo().m_trade_partner == 0 && (wmask & TRADE))
+	{
+		getGUIState()->m_shown_windows &= ~(TRADE | INVENTORY);
+		m_modified |= WINDOWS_MODIFIED;
+	}
+
+	if (player->isUsingWaypoint() && getGUIState()->m_shown_windows !=	WORLDMAP)
+	{
+		getGUIState()->m_shown_windows = WORLDMAP;
+		m_modified |= WINDOWS_MODIFIED;
+	}
+
+	if (!player->isUsingWaypoint() && (wmask & WORLDMAP))
+	{
+		getGUIState()->m_shown_windows &= ~WORLDMAP;
+		m_modified |= WINDOWS_MODIFIED;
+	}
+
+	/*
+	if (player->getRegion() !=0 && player->getRegion()->getCutsceneMode())
+	{
+		if ((getGUIState()->m_shown_windows & ~SAVE_EXIT) != 0)
+		{
+			getGUIState()->m_shown_windows &= SAVE_EXIT;
+			m_modified |= WINDOWS_MODIFIED;
+		}
+	}
+*/
+	if (m_gui_state.m_left_mouse_pressed)
+	{
+		m_gui_state.m_left_mouse_pressed_time += time;
+		if (m_gui_state.m_left_mouse_pressed_time >= 200 ||
+				  (m_gui_state.m_left_mouse_pressed_time >=40 && player->getAction()->m_type == "noaction") )
+		{
+			ClientCommand command;
+
+			command.m_button=LEFT_MOUSE_BUTTON;
+			if (m_gui_state.m_shift_hold)
+			{
+				command.m_button=LEFT_SHIFT_MOUSE_BUTTON;
+			}
+			updateClickedObjectId();
+
+			command.m_goal = m_gui_state.m_clicked;
+			command.m_id = m_gui_state.m_clicked_object_id;
+			command.m_action = player->getLeftAction();
+			command.m_number=0;
+
+			m_gui_state.m_left_mouse_pressed_time=0;
+			sendCommand(&command);
+
+		}
+	}
+
+	if (m_gui_state.m_right_mouse_pressed)
+	{
+		DEBUGX("rechte Maustaste festgehalten");
+		m_gui_state.m_right_mouse_pressed_time += time;
+
+		if (m_gui_state.m_right_mouse_pressed_time>= 200 ||
+				  (m_gui_state.m_left_mouse_pressed_time >=40 && player->getAction()->m_type == "noaction"))
+		{
+			ClientCommand command;
+			updateClickedObjectId();
+
+			command.m_button=RIGHT_MOUSE_BUTTON;
+			command.m_goal = m_gui_state.m_clicked;
+			command.m_id = m_gui_state.m_clicked_object_id;
+			command.m_action = player->getRightAction();
+			command.m_number=0;
+
+			m_gui_state.m_right_mouse_pressed_time=0;
+			sendCommand(&command);
+
+		}
+
+	}
+
+
+
+
+}
+
+void Document::updateClickedObjectId()
+{
+	Player* player = static_cast<Player*>(World::getWorld()->getLocalPlayer());
+	Region* reg = player->getRegion();
+	if (reg == 0)
+		return;
+
+	// select new target if the old one is gone or inactive
+	if (m_gui_state.m_clicked_object_id != 0 && m_gui_state.m_cursor_object_id != 0)
+	{
+		GameObject* go = reg->getObject(m_gui_state.m_clicked_object_id);
+		if (go == 0 || go->getState() != WorldObject::STATE_ACTIVE)
+		{
+			// TODO: better check if the target is appropriate for the action
+			go = reg->getObject(m_gui_state.m_cursor_object_id);
+			Creature* cr = dynamic_cast<Creature*>(go);
+			if ( cr != 0 && World::getWorld()->getRelation(player->getFraction(),cr) == Fraction::HOSTILE)
+			{
+				m_gui_state.m_clicked_object_id = m_gui_state.m_cursor_object_id;
+				DEBUGX("new target %i %i",m_gui_state.m_clicked_object_id, player->getId());
+			}
+		}
+	}
+}
+
+void Document::writeSavegame(bool writeShortkeys)
+{
+	if (getLocalPlayer()==0)
+		return;
+
+	CharConv* save;
+
+
+
+	std::stringstream* pstr = new std::stringstream;
+	save = new StdStreamConv(pstr);
+
+	getLocalPlayer()->toSavegame(save);
+
+	// Shortkeys hinzufuegen
+	if (writeShortkeys)
+	{
+		
+		ShortkeyMap::iterator it;
+		int nr =0;
+		for (it = m_ability_shortkey_map.begin(); it != m_ability_shortkey_map.end(); ++it)
+		{
+			if (it->second >= USE_SKILL_LEFT && it->second < USE_SKILL_RIGHT + 200)
+				nr ++;
+		}
+		save->printNewline();
+		save->toBuffer(nr);
+		save->printNewline();
+		for (it = m_ability_shortkey_map.begin(); it != m_ability_shortkey_map.end(); ++it)
+		{
+			if (it->second >= USE_SKILL_LEFT && it->second < USE_SKILL_RIGHT + 200)
+			{
+				save->toBuffer(static_cast<short>(it->first));
+				save->toBuffer(static_cast<short>(it->second));
+				save->printNewline();
+			}
+		}
+	}
+	else
+	{
+		save->printNewline();
+		save->toBuffer(0);
+	}
+
+	// Savegame schreiben (ansynchron)
+	std::pair<Document*, CharConv*>* param = new std::pair<Document*, CharConv*>(this,save);
+	
+	// Savegame schreiben
+	std::stringstream* stream = dynamic_cast<std::stringstream*> (static_cast<StdStreamConv*>(save)->getStream());
+	char* bp=0;
+	int len=0;
+	char bin ='0';
+	
+	// binary savegames are not used anymore
+	
+	
+	// Daten byteweise in Datei schreiben
+	std::ofstream file;
+	if (bin =='1')
+	{
+		file.open(m_save_file.c_str(),std::ios::out | std::ios::binary);
+	}
+	else
+	{
+		file.open(m_save_file.c_str());
+	}
+	if ( file.is_open() )
+	{
+		file << bin;
+		if (bin =='1')
+		{
+			file.write((char*) (&len),4);
+			file.write(bp,len);
+		}
+		else
+		{
+			file << stream->str();
+			DEBUGX("save: \n %s",stream->str().c_str());
+		}
+		
+		file.close();
+	}
+	else
+	{
+		ERRORMSG("cannot open save file: %s",m_save_file.c_str());
+	}
+	if (stream != 0)
+	{
+		delete stream;
+	}
+	
+
+}
+
+
+void Document::saveSettings()
+{
+    Options::getInstance()->writeToFile(SumwarsHelper::userPath() + "/options.xml");
+}
+
+void Document::loadSettings()
+{
+    Options::getInstance()->readFromFile(SumwarsHelper::userPath() + "/options.xml");
+}
+
+Player*  Document::getLocalPlayer()
+{
+	if (World::getWorld() ==0)
+		return m_temp_player;
+
+	return static_cast<Player*>(World::getWorld()->getLocalPlayer());
+}